예제 #1
0
    def test_tx(self):
        self.set_tx(Address.from_string(f"hx{'1234' * 10}"))
        self.score2.t_tx()  # On the upper line, set the tx property to pass the assert statement so that no exception is raised.

        self.set_tx(Address.from_string(f"hx{'12' * 20}"))
        self.assertRaises(AssertionError,
                          self.score2.t_tx)  # On the upper line, set the tx property not to pass the assert statement, and raise an exception.
 def setUp(self):
     super().setUp()
     self.mock_score = Address.from_string(f"cx{'abcd' * 10}")
     self.dividends = self.get_score_instance(Dividends, self.test_account1)
     self.wallet_array = [KeyWallet.load(v) for v in TEST_ACCOUNTS]
     account_info = {
         Address.from_string(wallet.get_address()): 10**21
         for wallet in self.wallet_array
     }
     self.initialize_accounts(account_info)
    def setUp(self):
        super().setUp()
        self.mock_score_address = Address.from_string(f"cx{'1234' * 10}")
        self.score2 = self.get_score_instance(
            SimpleScore2,
            self.test_account1,
            on_install_params={'score_address': self.mock_score_address})

        self.test_account3 = Address.from_string(f"hx{'12345' * 8}")
        self.test_account4 = Address.from_string(f"hx{'1234' * 10}")
        account_info = {self.test_account3: 10**21, self.test_account4: 10**21}
        self.initialize_accounts(account_info)
    def test_default_parameters(self):
        tx1 = self._make_deploy_tx("test_scores",
                                   "test_db_returns_default_value",
                                   self._addr_array[0],
                                   ZERO_SCORE_ADDRESS,
                                   deploy_params={})
        prev_block, tx_results = self._make_and_req_block([tx1])
        self._write_precommit_state(prev_block)
        self.assertEqual(tx_results[0].status, int(True))
        score_addr1 = tx_results[0].score_address

        val1 = 3
        val2 = "string"
        val3 = b'bytestring'
        val4 = Address.from_string(f"hx{'0'*40}")
        val5 = False
        val6 = Address.from_string(f"hx{'abcd1234'*5}")

        query_request = {
            "from": self._admin,
            "to": score_addr1,
            "dataType": "call",
            "data": {
                "method": "get_value1",
                "params": {}
            }
        }
        response = self._query(query_request)
        self.assertEqual(response, val1)

        query_request['data']['method'] = 'get_value2'
        response = self._query(query_request)
        self.assertEqual(response, val2)

        query_request['data']['method'] = 'get_value3'
        response = self._query(query_request)
        self.assertEqual(response, val3)

        query_request['data']['method'] = 'get_value4'
        response = self._query(query_request)
        self.assertEqual(response, val4)

        query_request['data']['method'] = 'get_value5'
        response = self._query(query_request)
        self.assertEqual(response, val5)

        query_request['data']['method'] = 'get_value6'
        response = self._query(query_request)
        self.assertEqual(response, val6)
예제 #5
0
    def test_canTransferByPartition(self):
        self.set_msg(self.test_account1)
        self.score.issueByPartition(
            "default", self.test_account2, 1000,
            b'minting 1000 tokens to test_account2 in default partition')
        self.score.issueByPartition(
            "locked", self.test_account2, 1000,
            b'minting 1000 tokens to test_account2 in locked partition')
        self.score.issueByPartition(
            "reserved", self.test_account2, 1000,
            b'minting 1000 tokens to test_account2 in reserved partition')

        self.set_msg(self.test_account2)
        reason = self.score.canTransferByPartition("random",
                                                   self.test_account2,
                                                   self.test_account3, 1000,
                                                   None)
        self.assertEqual(reason, "0x50 Invalid Partition")
        reason = self.score.canTransferByPartition("default",
                                                   self.test_account2,
                                                   self.test_account3, 1001,
                                                   None)
        self.assertEqual(reason, "0x52 Insufficient Balance")
        reason = self.score.canTransferByPartition(
            "default", self.test_account2,
            Address.from_prefix_and_int(AddressPrefix.EOA, 0), 1000, None)
        self.assertEqual(reason, "0x57 Invalid Receiver")
        reason = self.score.canTransferByPartition("default",
                                                   self.test_account2,
                                                   self.test_account3, 1000,
                                                   None)
        self.assertEqual(reason, "0x51 Transfer Successful")
    def test_default_parameters(self):
        tx_results: List['TransactionResult'] = self.deploy_score(
            score_root="sample_scores",
            score_name="sample_db_returns_default_value",
            from_=self._accounts[0],
            deploy_params={})
        score_address: 'Address' = tx_results[0].score_address

        val1 = 3
        val2 = "string"
        val3 = b'bytestring'
        val4 = Address.from_string(f"hx{'0' * 40}")
        val5 = False
        val6 = Address.from_string(f"hx{'abcd1234' * 5}")

        query_request = {
            "from": self._admin,
            "to": score_address,
            "dataType": "call",
            "data": {
                "method": "get_value1",
                "params": {}
            }
        }
        response = self._query(query_request)
        self.assertEqual(response, val1)

        query_request['data']['method'] = 'get_value2'
        response = self._query(query_request)
        self.assertEqual(response, val2)

        query_request['data']['method'] = 'get_value3'
        response = self._query(query_request)
        self.assertEqual(response, val3)

        query_request['data']['method'] = 'get_value4'
        response = self._query(query_request)
        self.assertEqual(response, val4)

        query_request['data']['method'] = 'get_value5'
        response = self._query(query_request)
        self.assertEqual(response, val5)

        query_request['data']['method'] = 'get_value6'
        response = self._query(query_request)
        self.assertEqual(response, val6)
예제 #7
0
 def __init__(self, serialized: bytes) -> None:
     self.__bytes = serialized
     self.__addresses = []
     if serialized is not None:
         self.__hash = get_hash(serialized)
         unpacked = rlp.rlp_decode(self.__bytes, {list: bytes})
         for b in unpacked:
             address = Address.from_bytes(b)
             self.__addresses.append(address)
예제 #8
0
 def from_string(s: str) -> 'Validators':
     if not isinstance(s, str) or len(s) < 1:
         return None
     splitted = s.split(",")
     addresses = []
     for a in splitted:
         try:
             addresses.append(Address.from_string(a).to_bytes())
         except BaseException as e:
             if len(splitted) == 1:
                 return Validators(base64.urlsafe_b64decode(s))
             else:
                 raise e
     b = rlp.rlp_encode(addresses)
     return Validators(b)
예제 #9
0
 def convert_from_bytes(param_type: str, v: bytes):
     if param_type == "int":
         return rlp.from_bytes(v, int)
     elif param_type == "str":
         return rlp.from_bytes(v, str)
     elif param_type == "bool":
         return rlp.from_bytes(v, bool)
     elif param_type == "bytes":
         return v
     elif param_type == "Address":
         return Address.from_bytes(v)
     else:
         raise BMVException(
             f"{param_type} is not supported type (only int, str, bool, Address, bytes are supported)"
         )
예제 #10
0
    def setUp(self):
        super().setUp()
        self.name = "IconHouseToken"
        self.symbol = "IHT"
        self.decimals = 18
        self.initial_supply = 0
        #self.controllable = 1

        params = {
            'name': self.name,
            'symbol': self.symbol,
            'decimals': self.decimals,
            'initial_supply': self.initial_supply,
            # 'controllable': self.controllable,
        }
        self.score = self.get_score_instance(SampleIRC16, self.test_account1,
                                             params)
        self.set_msg(self.test_account1)

        # self.test_account1 = hxe48913df85da204d99ac22e0180e017c82a5dc9b
        # self.test_account2 = hx541441378726178b4bce6d411765ee0b51bd7a03
        self.test_account3 = Address.from_string(f"hx{'12345'*8}")
        self.test_account4 = Address.from_string(f"hx{'1234'*10}")
        self.test_account5 = Address.from_string(f"hx{'4321'*10}")
예제 #11
0
    def test_handleRelayMessage(self):
        # ================================================
        #  test_block_update
        # ================================================

        block_updates = []
        _block_header = Dummy.block_header(1, self._validators.hash)
        _votes = Dummy.votes(_block_header, self._validators_with_key)
        _next_validators = None
        block_update = rlp.rlp_encode([_block_header._bytes, _votes._bytes, _next_validators])
        block_updates.append(block_update)
        block_proof = None
        receipt_proofs = []
        _msgs = rlp.rlp_encode([block_updates, block_proof, receipt_proofs])
        self.set_msg(Address.from_string(self._btp_bmc.contract))
        btp_msgs = self.score.handleRelayMessage(str(self._btp_bmc), str(self._btp_bmc), 1, base64.urlsafe_b64encode(_msgs))
        print(btp_msgs)
예제 #12
0
def _create_address_with_key(public_key: bytes):
    """Create an address with a given public key
    :param public_key: Public key based on secp256k1
    :return: Address created from a given public key or None if failed
    """
    # if isinstance(public_key, bytes):
    #     size = len(public_key)
    #     prefix: bytes = public_key[0]
    #
    #     if size == 33 and prefix in (0x02, 0x03):
    #         uncompressed_public_key: bytes = _convert_key(public_key)
    #     elif size == 65 and prefix == 0x04:
    #         uncompressed_public_key: bytes = public_key
    #     else:
    #         return None

    body: bytes = hashlib.sha3_256(public_key[1:]).digest()[-20:]
    return Address("0x", body)
예제 #13
0
파일: db.py 프로젝트: ilkereroglu/btp
 def get(self, k):
     if k in self.__remove:
         return None
     elif k in self.__cache:
         return self.__cache[k]
     else:
         b = self.__db[k]
         if b is None:
             if k in self.__default:
                 v = self.__default[k]
                 if isinstance(v, type) and issubclass(v, Serializable):
                     v = None
             else:
                 v = None
         elif b[0] == PropertiesDB.Type.INT:
             v = int.from_bytes(b[1:], "big", signed=True)
         elif b[0] == PropertiesDB.Type.STR:
             v = b[1:].decode('utf-8')
         elif b[0] == PropertiesDB.Type.BOOL:
             v = True if b[1:] == b'\x01' else False
         elif b[0] == PropertiesDB.Type.BYTES:
             v = b[1:]
         elif b[0] == PropertiesDB.Type.ADDRESS:
             v = Address.from_bytes(b[1:])
         elif b[0] == PropertiesDB.Type.BTPADDRESS:
             v = BTPAddress.from_bytes(b[1:])
         elif b[0] == PropertiesDB.Type.SERIALIZABLE:
             v = self.__default[k]
             if isinstance(v, type):
                 v = v.__new__(v)
             if isinstance(v, Serializable):
                 v = v.from_bytes(b[1:])
             else:
                 raise PropertiesDB.TypeException(
                     f"{type(v)} is not supported")
         else:
             raise PropertiesDB.TypeException(
                 f"{b[0]} is not supported type")
         self.__cache[k] = v
         return v
예제 #14
0
def address_by_public_key(public_key: bytes) -> Address:
    try:
        return create_address_with_key(public_key)
    except Exception as e:
        _check_recoverable_error(e)
        log_warning("fail to create_address_with_key, try coincurve")
        assert isinstance(public_key, bytes)
        assert len(public_key) in (33, 65)

        size = len(public_key)
        prefix: int = public_key[0]

        if size == 33 and prefix in (0x02, 0x03):
            uncompressed_public_key: bytes = _convert_key(public_key,
                                                          compressed=True)
        elif size == 65 and prefix == 0x04:
            uncompressed_public_key: bytes = public_key
        else:
            raise Exception("not supported public key length")

        body: bytes = hashlib.sha3_256(
            uncompressed_public_key[1:]).digest()[-20:]
        return Address(AddressPrefix.EOA, body)
    def test_transfer_from_approved(self):

        # Mint an NFT token first via 'mint'
        params = {'_to': self._test1.get_address(), '_tokenId': 1}
        transaction = CallTransactionBuilder() \
            .from_(self._test1.get_address()) \
            .to(self._score_address) \
            .step_limit(100_000_000) \
            .method("mint") \
            .params(params) \
            .build()

        signed_transaction = SignedTransaction(transaction, self._test1)
        tx_result = self.process_transaction(signed_transaction,
                                             self.icon_service)
        self.assertTrue('status' in tx_result)
        self.assertEqual(1, tx_result['status'])

        # Approve token operation to new wallet via 'approve'
        params = {'_to': self._wallet_array[0].get_address(), '_tokenId': 1}
        transaction = CallTransactionBuilder() \
            .from_(self._test1.get_address()) \
            .to(self._score_address) \
            .step_limit(100_000_000) \
            .method("approve") \
            .params(params) \
            .build()

        signed_transaction = SignedTransaction(transaction, self._test1)
        tx_result = self.process_transaction(signed_transaction,
                                             self.icon_service)
        self.assertTrue('status' in tx_result)
        self.assertEqual(1, tx_result['status'])

        # Check approval of token 1 via 'getApproval'
        # owner of token 1 should be self._test1
        # approvee of token 1 should be self._wallet_array[0]

        params = {"_tokenId": 1}
        call = CallBuilder().from_(self._test1.get_address()) \
            .to(self._score_address) \
            .method("getApproved") \
            .params(params) \
            .build()

        response = self.process_call(call, self.icon_service)
        self.assertEqual(response, self._wallet_array[0].get_address())

        # Transfer ownership of token 1 from self._test1 to self._wallet_array[1] by its operator approvee self._wall_array[0] using 'transferFrom'
        params = {
            '_from': self._test1.get_address(),
            '_to': self._wallet_array[1].get_address(),
            '_tokenId': 1
        }
        transaction = CallTransactionBuilder() \
            .from_(self._test1.get_address()) \
            .to(self._score_address) \
            .step_limit(100_000_000) \
            .method("transferFrom") \
            .params(params) \
            .build()

        signed_transaction = SignedTransaction(transaction, self._test1)
        tx_result = self.process_transaction(signed_transaction,
                                             self.icon_service)
        self.assertTrue('status' in tx_result)
        self.assertEqual(1, tx_result['status'])

        # Check new ownership of token 1, expected to be self._wallet_array[1]
        params = {"_tokenId": 1}
        call = CallBuilder().from_(self._test1.get_address()) \
            .to(self._score_address) \
            .method("ownerOf") \
            .params(params) \
            .build()

        response = self.process_call(call, self.icon_service)
        self.assertEqual(response, self._wallet_array[1].get_address())

        # Check token 1's new approved operator, expected zero address
        params = {"_tokenId": 1}
        call = CallBuilder().from_(self._test1.get_address()) \
            .to(self._score_address) \
            .method("getApproved") \
            .params(params) \
            .build()

        response = self.process_call(call, self.icon_service)
        self.assertEqual(
            response, str(Address.from_prefix_and_int(AddressPrefix.EOA, 0)))

        # Check token count of self._test1, expected 0
        params = {"_owner": self._test1.get_address()}
        call = CallBuilder().from_(self._test1.get_address()) \
            .to(self._score_address) \
            .method("balanceOf") \
            .params(params) \
            .build()

        response = self.process_call(call, self.icon_service)
        self.assertEqual(response, hex(0))

        # Last we burn the token from the new owner self._wallet_array[1]
        params = {
            "_tokenId": 1,
        }
        transaction = CallTransactionBuilder() \
            .from_(self._wallet_array[1].get_address()) \
            .to(self._score_address) \
            .step_limit(100_000_000) \
            .method("burn") \
            .params(params) \
            .build()

        signed_transaction = SignedTransaction(transaction,
                                               self._wallet_array[1])
        tx_result = self.process_transaction(signed_transaction,
                                             self.icon_service)
        self.assertTrue('status' in tx_result)
        self.assertEqual(1, tx_result['status'])

        # Check owner of token 1, expect invalid owner (zero address)
        params = {"_tokenId": 1}
        call = CallBuilder().from_(self._test1.get_address()) \
            .to(self._score_address) \
            .method("ownerOf") \
            .params(params) \
            .build()

        with self.assertRaises(IconScoreException) as e:
            self.process_call(call, self.icon_service)
        self.assertEqual(e.exception.code, 32)
        self.assertEqual(e.exception.message,
                         "Invalid _tokenId. NFT is burned")
예제 #16
0
    def setUp(self):
        super().setUp()
        self.test_admin_account = Address.from_string(f"hx{'1574' * 10}")
        self.test_account3 = Address.from_string(f"hx{'1238' * 10}")
        self.test_account4 = Address.from_string(f"hx{'1237' * 10}")
        self.test_account5 = Address.from_string(f"hx{'1236' * 10}")
        self.test_account6 = Address.from_string(f"hx{'2365' * 10}")
        self.test_account7 = Address.from_string(f"hx{'6964' * 10}")
        self.initialize_accounts({self.test_account1: 100000 * 10**18})

        self.cps_score_address = Address.from_string(f"cx{'1234' * 10}")
        self.cps_treasury_score = Address.from_string(f"cx{'3456' * 10}")
        self.cpf_treasury_score = Address.from_string(f"cx{'5678' * 10}")
        self.bnUSD_score = Address.from_string(f"cx{'7890' * 10}")
        self.sICX_score = Address.from_string(f"cx{'1985' * 10}")
        self.dex_score = Address.from_string(f"cx{'2000' * 10}")
        self.staking_score = Address.from_string(f"cx{'2001' * 10}")

        self.initialize_accounts({self.cpf_treasury_score: 100000 * 10**18})

        self.test_contract_1 = Address.from_string(f"cx{'6789' * 10}")
        self.set_msg(self.test_account1)
        self.set_tx(self.test_account1)
        self.cpf_score = self.get_score_instance(
            CPF_TREASURY,
            self.test_account1,
            on_install_params={},
            score_address=self.cpf_treasury_score)
예제 #17
0
 def __init__(self):
     self.test_account3 = Address.from_string(f"hx{'1238' * 10}")
# See the License for the specific language governing permissions and
# limitations under the License.

from iconservice import ZERO_SCORE_ADDRESS, Address
from tests.integrate_test.test_integrate_base import TestIntegrateBase

ONE = '1'
ZERO = '0'
EMPTY_STR = ""
EMPTY_BYTE = bytes.hex(b"")
NUM1 = 1
NUM0 = 0
INT_VAL = '0x14'
STRING_VAL = 'string value'
BYTE_VAL = bytes.hex(b'byte string')
ADDRESS_VAL = str(Address.from_string(f"hx{'abcd1234' * 5}"))
BOOL_VAL = hex(False)


class TestIntegrateMethodParamters(TestIntegrateBase):
    def test_int_type_parameters_methods(self):
        tx1 = self._make_deploy_tx("test_scores",
                                   "test_db_returns",
                                   self._addr_array[0],
                                   ZERO_SCORE_ADDRESS,
                                   deploy_params={
                                       "value": str(self._addr_array[1]),
                                       "value1": str(self._addr_array[1])
                                   })

        prev_block, tx_results = self._make_and_req_block([tx1])
    def test_address_type_parameters_methods(self):
        tx1 = self._make_deploy_tx("test_scores",
                                   "test_db_returns",
                                   self._addr_array[0],
                                   ZERO_SCORE_ADDRESS,
                                   deploy_params={
                                       "value": str(self._addr_array[1]),
                                       "value1": str(self._addr_array[1])
                                   })

        prev_block, tx_results = self._make_and_req_block([tx1])
        self._write_precommit_state(prev_block)
        self.assertEqual(tx_results[0].status, int(True))
        score_addr1 = tx_results[0].score_address
        query_request = {
            "from": self._admin,
            "to": score_addr1,
            "dataType": "call",
            "data": {
                "method": "get_value4",
                "params": {}
            }
        }
        response = self._query(query_request)
        self.assertEqual(response,
                         self._addr_array[1])  # original value: 0(int)

        # set value to '1' -> fail
        tx = self._make_score_call_tx(self._addr_array[0],
                                      score_addr1,
                                      'set_value4', {"value": ONE},
                                      pre_validation_enabled=False)
        prev_block, tx_results = self._make_and_req_block([tx])
        self._write_precommit_state(prev_block)
        self.assertEqual(tx_results[0].status, int(False))

        # set value to '0' -> fail
        tx = self._make_score_call_tx(self._addr_array[0],
                                      score_addr1,
                                      'set_value4', {"value": ZERO},
                                      pre_validation_enabled=False)
        prev_block, tx_results = self._make_and_req_block([tx])
        self._write_precommit_state(prev_block)
        self.assertEqual(tx_results[0].status, int(False))

        # set value to '' fail
        tx = self._make_score_call_tx(self._addr_array[0],
                                      score_addr1,
                                      'set_value4', {"value": EMPTY_STR},
                                      pre_validation_enabled=False)
        prev_block, tx_results = self._make_and_req_block([tx])
        self._write_precommit_state(prev_block)
        self.assertEqual(tx_results[0].status, int(False))

        # set value to b'' fail
        tx = self._make_score_call_tx(self._addr_array[0],
                                      score_addr1,
                                      'set_value4', {"value": EMPTY_BYTE},
                                      pre_validation_enabled=False)
        prev_block, tx_results = self._make_and_req_block([tx])
        self._write_precommit_state(prev_block)
        self.assertEqual(tx_results[0].status, int(False))

        # set value to None -> fail

        tx = self._make_score_call_tx(self._addr_array[0],
                                      score_addr1,
                                      'set_value4', {"value": None},
                                      pre_validation_enabled=False)
        prev_block, tx_results = self._make_and_req_block([tx])
        self._write_precommit_state(prev_block)
        self.assertEqual(tx_results[0].status, int(False))

        # set value to 1 -> fail
        tx = self._make_score_call_tx(self._addr_array[0],
                                      score_addr1,
                                      'set_value4', {"value": NUM1},
                                      pre_validation_enabled=False)
        prev_block, tx_results = self._make_and_req_block([tx])
        self._write_precommit_state(prev_block)
        self.assertEqual(tx_results[0].status, int(False))

        # set value to 0 -> fail
        tx = self._make_score_call_tx(self._addr_array[0],
                                      score_addr1,
                                      'set_value4', {"value": NUM0},
                                      pre_validation_enabled=False)
        prev_block, tx_results = self._make_and_req_block([tx])
        self._write_precommit_state(prev_block)
        self.assertEqual(tx_results[0].status, int(False))

        # set value to '0x14'
        tx = self._make_score_call_tx(self._addr_array[0],
                                      score_addr1,
                                      'set_value4', {"value": INT_VAL},
                                      pre_validation_enabled=False)
        prev_block, tx_results = self._make_and_req_block([tx])
        self._write_precommit_state(prev_block)
        self.assertEqual(tx_results[0].status, int(False))

        # set value to 'string value''
        tx = self._make_score_call_tx(self._addr_array[0],
                                      score_addr1,
                                      'set_value4', {"value": STRING_VAL},
                                      pre_validation_enabled=False)
        prev_block, tx_results = self._make_and_req_block([tx])
        self._write_precommit_state(prev_block)
        self.assertEqual(tx_results[0].status, int(False))

        # set value to b'byte value'
        tx = self._make_score_call_tx(self._addr_array[0],
                                      score_addr1,
                                      'set_value4', {"value": BYTE_VAL},
                                      pre_validation_enabled=False)
        prev_block, tx_results = self._make_and_req_block([tx])
        self._write_precommit_state(prev_block)
        self.assertEqual(tx_results[0].status, int(False))

        # set value to address value
        tx = self._make_score_call_tx(self._addr_array[0],
                                      score_addr1,
                                      'set_value4', {"value": ADDRESS_VAL},
                                      pre_validation_enabled=False)
        prev_block, tx_results = self._make_and_req_block([tx])
        self._write_precommit_state(prev_block)
        self.assertEqual(tx_results[0].status, int(True))
        response = self._query(query_request)
        self.assertEqual(response, Address.from_string(ADDRESS_VAL))

        # set value to False
        tx = self._make_score_call_tx(self._addr_array[0],
                                      score_addr1,
                                      'set_value4', {"value": BOOL_VAL},
                                      pre_validation_enabled=False)
        prev_block, tx_results = self._make_and_req_block([tx])
        self._write_precommit_state(prev_block)
        self.assertEqual(tx_results[0].status, int(False))
예제 #20
0
 def score_address() -> Address:
     return Address.from_data(AddressPrefix.CONTRACT, secrets.token_bytes(Dummy.ICON_ADDRESS_BODY_SIZE))
예제 #21
0
 def address() -> Address:
     return Address.from_data(AddressPrefix.EOA, secrets.token_bytes(Dummy.ICON_ADDRESS_BODY_SIZE))
예제 #22
0
 def raw_to_object(self, raw):
     return self.new_relayer(Address.from_string(raw))
class TestSmartWallet(TestCase):
    sender = Address(AddressPrefix(0), b"1" * 20)

    def setUp(self):
        self.key_value_mock = MockKeyValueDatabase({})
        self.db = IconScoreDatabase(self.sender,
                                    ContextDatabase(self.key_value_mock))
        IconScoreBase.get_owner = lambda score_object, score_address: self.sender

        self.smart_wallet = SmartWallet(self.db)
        type(self.smart_wallet).msg = PropertyMock(
            return_value=Message(sender=self.sender, value=10000))

        # print test name
        print(f"===== {self._testMethodName} ==========================")

    def tearDown(self):
        print("=================================================")

    def test_add_account(self):
        """
        GIVEN account to put
        WHEN on_install and call from the method `add_account`
        THEN _accounts have all of accounts (3)
        """
        # GIVEN
        SmartWallet.Account = lambda _self, acccount: None
        # WHEN
        sample_account = {
            "id": 0,
            "tokenType": "test_token_type",
            "contractAddr": "test_contract_addr",
            "balance": "test_balance",
            "sendLimit": "test_send_limit",
            "totalUsed": "test_total_used",
            "lastUsedDate": "test_last_used_date",
            "dids": "test_dids"
        }
        str_sample_account = json.dumps(sample_account)
        self.smart_wallet.on_install(str_sample_account)
        self.smart_wallet.add_account(str_sample_account)
        self.smart_wallet.add_account(str_sample_account)
        # THEN
        assert len(self.smart_wallet._accounts) == 3

    def test_change_setting_value(self):
        """
        GIVEN the previous account
        WHEN the previous account is updated
        THEN the account change to the new one
        """
        # GIVEN
        SmartWallet.Account = lambda _self, account: None
        sample_account = {
            "id": 0,
            "tokenType": "test_token_type",
            "contractAddr": "test_contract_addr",
            "balance": "test_balance",
            "sendLimit": "test_send_limit",
            "totalUsed": "test_total_used",
            "lastUsedDate": "test_last_used_date",
            "dids": "test_dids"
        }
        str_sample_account = json.dumps(sample_account)
        self.smart_wallet.on_install(str_sample_account)
        self.smart_wallet.add_account(str_sample_account)
        # WHEN
        sample_account["id"] = 1
        sample_account["tokenType"] = "new"
        str_sample_account = json.dumps(sample_account)
        self.smart_wallet._change_setting_value(account=str_sample_account)
        json_sample_account = json.loads(self.smart_wallet._accounts[1])
        # THEN
        self.assertEqual(json_sample_account["tokenType"], "new")

    @only_owner
    def _test_only_owner(self):
        pass

    def test_only_owner(self):
        self.msg = MagicMock(return_value=self.smart_wallet.owner)
        self.msg.sender = self.msg()
        self.owner = self.msg()
        self._test_only_owner()

        self.msg.sender = 123
        self.assertRaises(AttributeError, self._test_only_owner)
class TestWalletManager(TestCase):
    sender = Address(AddressPrefix(0), b"1" * 20)

    def setUp(self):
        self.key_value_mock = MockKeyValueDatabase({})
        self.db = IconScoreDatabase(self.sender,
                                    ContextDatabase(self.key_value_mock))
        IconScoreBase.get_owner = lambda score_object, score_address: self.sender

        self.smart_wallet = SmartWallet(self.db)
        type(self.smart_wallet).msg = PropertyMock(
            return_value=Message(sender=self.sender, value=10000))
        SmartWallet.Account = lambda _self, account: None
        self.smart_wallet.on_install(
            json.dumps({
                "id": 0,
                "tokenType": "icx",
                "balance": 3000,
                "sendLimit": 1000,
                "totalUsed": 500,
                "lastUsedDate": "2018-11-21",
                "dids": []
            }))
        # print test name
        print("=====================================================")
        print(f"{self._testMethodName}")

    def tearDown(self):
        print(f"end test")
        print("=====================================================")

    def test_transfer_direct_send(self):
        """GIVEN an account that has token icx and required did is nothing
        WHEN send icx lower than today used_limits
        THEN account update balance and limit and register event send_transaction
        """
        # GIVEN
        self.__setup_no_did_transfer_env()

        def TransferSuccessMock(contract, account_id: int, token_type: str,
                                token_address: str, to: str, amount: int):
            self.assertEqual(0, account_id)
            self.assertEqual("icx", token_type)
            self.assertEqual("", token_address)
            self.assertEqual("hx111111111111111111111111111111111111111111",
                             to)
            self.assertEqual(500, amount)

        SmartWallet.TransferSuccess = TransferSuccessMock

        # WHEN
        self.smart_wallet.transfer(
            account_id=0,
            token_type="icx",
            contract_addr="",
            to="hx111111111111111111111111111111111111111111",
            amount=500)

        # THEN
        updated_account = json.loads(self.smart_wallet._accounts[0])
        self.assertEqual(updated_account["totalUsed"], 1000)
        self.assertEqual(updated_account["balance"], 2500)

    def __setup_no_did_transfer_env(self):
        Icx.transfer = lambda contract, addr_to, amount: None
        self.smart_wallet._accounts = [
            json.dumps({
                "id": 0,
                "tokenType": "icx",
                "balance": 3000,
                "sendLimit": 1000,
                "totalUsed": 500,
                "lastUsedDate": "2018-11-21",
                "dids": []
            })
        ]
        type(self.smart_wallet).block = PropertyMock(
            return_value=Block(0, 1542773377))

    def test_transfer_amount_is_higher_than_balance_must_raise_revert(self):
        # GIVEN
        self.__setup_no_did_transfer_env()
        # WHEN THEN

        self.assertRaises(RevertException,
                          self.smart_wallet.transfer,
                          account_id=0,
                          token_type="icx",
                          contract_addr="",
                          to="hx111111111111111111111111111111111111111111",
                          amount=3500)

    def test_transfer_amount_is_higher_than_left_today_limit_must_raise_revert(
            self):
        # GIVEN
        self.__setup_no_did_transfer_env()
        # WHEN THEN

        self.assertRaises(RevertException,
                          self.smart_wallet.transfer,
                          account_id=0,
                          token_type="icx",
                          contract_addr="",
                          to="hx111111111111111111111111111111111111111111",
                          amount=600)

    def test_transfer_amount_is_higher_than_left_today_limit_but_can_if_day_change(
            self):
        # GIVEN
        self.__setup_no_did_transfer_env()
        # setup last date is 11_21
        ts_11_23 = 1542993377
        type(self.smart_wallet).block = PropertyMock(
            return_value=Block(0, ts_11_23))

        # THEN
        def TransferSuccessMock(contract, account_id: int, token_type: str,
                                token_address: str, to: str, amount: int):
            self.assertEqual(0, account_id)
            self.assertEqual("icx", token_type)
            self.assertEqual("", token_address)
            self.assertEqual("hx111111111111111111111111111111111111111111",
                             to)
            self.assertEqual(600, amount)

        SmartWallet.TransferSuccess = TransferSuccessMock
        # WHEN
        self.smart_wallet.transfer(
            account_id=0,
            token_type="icx",
            contract_addr="",
            to="hx111111111111111111111111111111111111111111",
            amount=600)
        # THEN
        account = json.loads(self.smart_wallet._accounts[0])
        self.assertEqual(2400, account["balance"])
        self.assertEqual(600, account["totalUsed"])
        self.assertEqual("2018-11-23", account["lastUsedDate"])

    def test_pending_transaction(self):
        """ GIVEN account with did_list not empty
        WHEN call transfer with transferable info
        THEN a transaction will be pending
        """
        # GIVEN
        self.__setup_processing_pending_tx()

        # THEN
        def PendingMock(_self, pending_tx: str):
            print(pending_tx)
            pending_tx_as_dict = json.loads(pending_tx)
            self.assertEqual(1, pending_tx_as_dict["id"])
            self.assertEqual(0, pending_tx_as_dict["from"])
            self.assertEqual("hx" + "1" * 40, pending_tx_as_dict["to"])
            self.assertEqual("icx", pending_tx_as_dict["tokenType"])
            self.assertEqual("", pending_tx_as_dict["contractAddr"])
            self.assertEqual(500, pending_tx_as_dict["amount"])
            self.assertEqual(["kakao", "chainId"], pending_tx_as_dict["dids"])

        SmartWallet.Pending = PendingMock

        # WHEN
        self.smart_wallet.transfer(account_id=0,
                                   token_type="icx",
                                   contract_addr="",
                                   to="hx" + "1" * 40,
                                   amount=500)

        # THEN
        pending_tx_db = DictDB(PENDING_TX, self.smart_wallet.db, str, 1)
        pending_tx_as_dict = json.loads(pending_tx_db[1])
        self.assertEqual(1, pending_tx_as_dict["id"])
        self.assertEqual(0, pending_tx_as_dict["from"])
        self.assertEqual("hx" + "1" * 40, pending_tx_as_dict["to"])
        self.assertEqual("icx", pending_tx_as_dict["tokenType"])
        self.assertEqual("", pending_tx_as_dict["contractAddr"])
        self.assertEqual(500, pending_tx_as_dict["amount"])
        self.assertEqual(["kakao", "chainId"], pending_tx_as_dict["dids"])

        pending_tx_list = json.loads(
            VarDB(PENDING_TX_ID_LIST, self.smart_wallet.db, str).get())
        self.assertEqual(1, len(pending_tx_list))
        self.assertEqual(1, pending_tx_list[0])

        last_tx_id = VarDB(LAST_TX_ID, self.smart_wallet.db, int).get()
        self.assertEqual(1, last_tx_id)

    def __setup_processing_pending_tx(self):
        Icx.transfer = lambda contract, addr_to, amount: None
        self.smart_wallet._accounts = [
            json.dumps({
                "id": 0,
                "tokenType": "icx",
                "balance": 3000,
                "sendLimit": 1000,
                "totalUsed": 500,
                "lastUsedDate": "2018-11-21",
                "dids": ["kakao", "chainId"]
            })
        ]
        type(self.smart_wallet).block = PropertyMock(
            return_value=Block(0, 1542773377))

    def test_approval(self):
        """ GIVEN account with two dids, and pending one tx from that account,
        WHEN call approval twice
        THEN first approval remove dids in pending tx, second remove pending tx
        with TransferSuccess event
        """
        # GIVEN
        self.__setup_processing_pending_tx()
        SmartWallet.Pending = lambda _self, pending_tx: None

        self.smart_wallet.transfer(account_id=0,
                                   token_type="icx",
                                   contract_addr="",
                                   to="hx" + "1" * 40,
                                   amount=500)

        # first WHEN
        def FirstApprovalMock(_self, tx_id, did):
            self.assertEqual(1, tx_id)
            self.assertEqual("kakao", did)

        SmartWallet.Approval = FirstApprovalMock
        self.smart_wallet.approval(1, "kakao", "true")

        # first THEN
        pending_tx_db = DictDB(PENDING_TX, self.smart_wallet.db, str, 1)
        pending_tx_as_dict = json.loads(pending_tx_db[1])
        self.assertEqual(["chainId"], pending_tx_as_dict["dids"])

        # second WHEN
        def SecondApprovalMock(_self, tx_id, did):
            self.assertEqual(1, tx_id)
            self.assertEqual("chainId", did)

        SmartWallet.Approval = SecondApprovalMock
        SmartWallet.TransferSuccess = lambda _self, account_id, token_type, contract_addr, to, amount: None

        self.smart_wallet.approval(1, "chainId", "true")

        # second THEN
        self.assertEqual("", pending_tx_db[1])
        self.assertEqual(
            json.dumps([]),
            VarDB(PENDING_TX_ID_LIST, self.smart_wallet.db, str).get())

    def test_transfer_account_to_account(self):
        """ GIVEN two accounts
        WHEN to address is 1
        THEN transfer success to account
        """
        # GIVEN
        self.__setup_no_did_transfer_env()
        self.smart_wallet._accounts\
            .append(json.dumps({
                    "id": 1,
                    "tokenType": "icx",
                    "balance": 3000,
                    "sendLimit": 1000,
                    "totalUsed": 500,
                    "lastUsedDate": "2018-11-21",
                    "dids": ["kakao", "chainId"]
            })
        )

        def TransferSuccessMock(contract, account_id: int, token_type: str,
                                token_address: str, to: str, amount: int):
            self.assertEqual(0, account_id)
            self.assertEqual("icx", token_type)
            self.assertEqual("", token_address)
            self.assertEqual("1", to)
            self.assertEqual(500, amount)

        SmartWallet.TransferSuccess = TransferSuccessMock

        self.smart_wallet.transfer(0, "icx", "", "1", 500)

        # THEN
        account0 = json.loads(self.smart_wallet._accounts[0])
        assert account0['balance'] == 2500
        assert account0['totalUsed'] == 1000

        account1 = json.loads(self.smart_wallet._accounts[1])
        assert account1['balance'] == 3500
예제 #25
0
# limitations under the License.
import copy
from unittest.mock import PropertyMock

import pytest

from iconservice import Address
from iconservice.base.block import Block
from iconservice.icon_constant import Revision, IconScoreContextType
from iconservice.iconscore.context.context import ContextContainer
from iconservice.iconscore.icon_score_context import IconScoreContext
from iconservice.icx.coin_part import CoinPart, CoinPartFlag, CoinPartType
from iconservice.icx.icx_account import Account
from iconservice.icx.stake_part import StakePart

ADDRESS = Address.from_string(f"hx{'1234'*10}")
UNSTAKE_LOCK_PERIOD = 20
WITHDRAWAL_AMOUNT = 10


@pytest.fixture(scope="function")
def context():
    ctx = IconScoreContext(IconScoreContextType.DIRECT)
    block = Block(0, None, 0, None, 0)
    ctx.block = block
    ContextContainer._push_context(ctx)
    yield ctx
    ContextContainer._pop_context()


class TestAccount: