Exemplo n.º 1
0
    def test_ghost_multi_mint(self):
        engine = self.prepare_testengine()
        engine.add_contract(self.CONTRACT_PATH_NEF.replace('.py', '.nef'))
        aux_path = self.get_contract_path('test_native', 'auxiliary_contract.py')
        output, manifest = self.compile_and_save(self.CONTRACT_PATH_NEF.replace('.nef', '.py'))
        ghost_address = hash160(output)
        print(to_hex_str(ghost_address))
        output, manifest = self.compile_and_save(aux_path)
        aux_address = hash160(output)
        print(to_hex_str(aux_address))

        # when deploying, the contract will mint tokens to the owner
        deploy_event = engine.get_events('Deployed')
        self.assertEqual(1, len(deploy_event))
        self.assertEqual(2, len(deploy_event[0].arguments))

        # add some gas for fees
        add_amount = 10 * 10 ** 8
        engine.add_gas(aux_address, add_amount)

        # define custom meta & lock & royalties for multi
        tokenMeta = [
                bytes('{ "name": "GHOST", "description": "A ghost shows up", "image": "{some image URI}", "tokenURI": "{some URI}" }', 'utf-8'),
                bytes('{ "name": "GHOST2", "description": "A ghost shows up", "image": "{some image URI}", "tokenURI": "{some URI}" }', 'utf-8'),
                bytes('{ "name": "GHOST3", "description": "A ghost shows up", "image": "{some image URI}", "tokenURI": "{some URI}" }', 'utf-8')
            ]

        lockedContent = [
                bytes('123', 'utf-8'),
                bytes('456', 'utf-8'),
                bytes('789', 'utf-8'),
            ]

        royalties = [
                bytes('[{"address": "someaddress", "value": 20}, {"address": "someaddress2", "value": 30}]', 'utf-8'),
                bytes('[{"address": "someaddress3", "value": 20}, {"address": "someaddress4", "value": 30}]', 'utf-8'),
                bytes('[{"address": "someaddress5", "value": 20}, {"address": "someaddress6", "value": 30}]', 'utf-8'),
            ]

        # check tokens iterator before
        ghost_tokens_before = self.run_smart_contract(engine, self.CONTRACT_PATH_NEF, 'tokens', expected_result_type=InteropInterface)
        self.assertEqual(InteropInterface, ghost_tokens_before)

        # multiMint
        result = self.run_smart_contract(engine, self.CONTRACT_PATH_NEF, 'multiMint', 
                aux_address, tokenMeta, lockedContent, royalties, None,
                signer_accounts=[aux_address],
                expected_result_type=list)
        print("result: " + str(result))

        # check tokens iterator after
        ghost_tokens_after = self.run_smart_contract(engine, self.CONTRACT_PATH_NEF, 'tokens', expected_result_type=InteropInterface)
        print("tokens after: " + str(ghost_tokens_after))
        
        # check balances after
        ghost_balance_after = self.run_smart_contract(engine, self.CONTRACT_PATH_NEF, 'balanceOf', aux_address)
        self.assertEqual(3, ghost_balance_after)
        ghost_supply_after = self.run_smart_contract(engine, self.CONTRACT_PATH_NEF, 'totalSupply')
        self.assertEqual(3, ghost_supply_after)
        self.print_notif(engine.notifications)
Exemplo n.º 2
0
    def test_ghost_onNEP11Payment(self):
        engine = self.prepare_testengine()
        engine.add_contract(self.CONTRACT_PATH_NEF.replace('.py', '.nef'))
        aux_path = self.get_contract_path('test_native', 'auxiliary_contract.py')
        output, manifest = self.compile_and_save(self.CONTRACT_PATH_NEF.replace('.nef', '.py'))
        ghost_address = hash160(output)
        print(to_hex_str(ghost_address))
        output, manifest = self.compile_and_save(aux_path)
        aux_address = hash160(output)
        print(to_hex_str(aux_address))

        # add some gas for fees
        add_amount = 10 * 10 ** 8
        engine.add_gas(self.OTHER_ACCOUNT_1, add_amount)

        # mint
        token = self.run_smart_contract(engine, self.CONTRACT_PATH_NEF, 'mint', 
            self.OTHER_ACCOUNT_1, self.TOKEN_META, self.LOCK_CONTENT, self.ROYALTIES, None,
            signer_accounts=[self.OTHER_ACCOUNT_1],
            expected_result_type=bytes)

        # the smart contract will abort if any address calls the NEP11 onPayment method
        with self.assertRaises(TestExecutionException, msg=self.ABORTED_CONTRACT_MSG):
            result = self.run_smart_contract(engine, self.CONTRACT_PATH_NEF, 'onNEP11Payment', 
                self.OTHER_ACCOUNT_1, 1, token, None,
                signer_accounts=[self.OTHER_ACCOUNT_1],
                expected_result_type=bool)
Exemplo n.º 3
0
    def test_ghost_mint(self):
        engine = self.prepare_testengine()
        engine.add_contract(self.CONTRACT_PATH_NEF.replace('.py', '.nef'))
        aux_path = self.get_contract_path('test_native', 'auxiliary_contract.py')
        output, manifest = self.compile_and_save(self.CONTRACT_PATH_NEF.replace('.nef', '.py'))
        ghost_address = hash160(output)
        print(to_hex_str(ghost_address))
        output, manifest = self.compile_and_save(aux_path)
        aux_address = hash160(output)
        print(to_hex_str(aux_address))

        # when deploying, the contract will mint tokens to the owner
        deploy_event = engine.get_events('Deployed')
        self.assertEqual(1, len(deploy_event))
        self.assertEqual(2, len(deploy_event[0].arguments))

        # should fail because account does not have enough for fees
        with self.assertRaises(TestExecutionException, msg=self.ASSERT_RESULTED_FALSE_MSG):
            self.run_smart_contract(engine, self.CONTRACT_PATH_NEF, 'mint', 
                # aux_address, self.TOKEN_META, self.LOCK_CONTENT, self.ROYALTIES, None,
                aux_address, bytes(0), bytes(0), bytes(0), None,
                signer_accounts=[aux_address],
                expected_result_type=bytes)

        # add some gas for fees
        add_amount = 10 * 10 ** 8
        engine.add_gas(aux_address, add_amount)

        # should succeed now that account has enough fees
        token = self.run_smart_contract(engine, self.CONTRACT_PATH_NEF, 'mint', 
                aux_address, self.TOKEN_META, self.LOCK_CONTENT, self.ROYALTIES, None,
                signer_accounts=[aux_address],
                expected_result_type=bytes)

        print("get props now: ")
        properties = self.run_smart_contract(engine, self.CONTRACT_PATH_NEF, 'properties', token, expected_result_type=bytes)
        print("props: " + str(properties))
        royalties = self.run_smart_contract(engine, self.CONTRACT_PATH_NEF, 'getRoyalties', token, expected_result_type=bytes)
        print("royalties: " + str(royalties))

        print('non existing props:')
        with self.assertRaises(TestExecutionException, msg='An unhandled exception was thrown. Unable to parse metadata'):
            properties = self.run_smart_contract(engine, self.CONTRACT_PATH_NEF, 'properties',
                    bytes('thisisanonexistingtoken', 'utf-8'), expected_result_type=bytes)
        print("props: " + str(properties))

        # check balances after
        ghost_amount_after = self.run_smart_contract(engine, GAS_SCRIPT, 'balanceOf', ghost_address)
        gas_aux_after = self.run_smart_contract(engine, GAS_SCRIPT, 'balanceOf', aux_address)
        print("ghost gas amount: " + str(ghost_amount_after))
        print("aux gas amount: " + str(gas_aux_after))
        ghost_balance_after = self.run_smart_contract(engine, self.CONTRACT_PATH_NEF, 'balanceOf', aux_address)
        print("balance nft: " + str(ghost_balance_after))
        ghost_supply_after = self.run_smart_contract(engine, self.CONTRACT_PATH_NEF, 'totalSupply')
        print("supply nft: " + str(ghost_supply_after))
        self.assertEqual(1, ghost_supply_after)
        self.print_notif(engine.notifications)
Exemplo n.º 4
0
 def to_json(self) -> Dict[str, Any]:
     return {
         'signers': [signer.to_json() for signer in self._signers],
         'witnesses': [witness.to_json() for witness in self._witnesses],
         'attributes': [attr.to_json() for attr in self._attributes],
         'script': to_hex_str(self._script)
     }
Exemplo n.º 5
0
    def _nef_hash(self) -> str:
        """
        Gets the string representation of the hash of the nef file

        :return: the hex string representation of the hash
        """
        return to_hex_str(self._nef.script_hash)
Exemplo n.º 6
0
    def test_ghost_pause(self):
        engine = self.prepare_testengine()
        engine.add_contract(self.CONTRACT_PATH_NEF.replace('.py', '.nef'))
        aux_path = self.get_contract_path('test_native', 'auxiliary_contract.py')
        output, manifest = self.compile_and_save(self.CONTRACT_PATH_NEF.replace('.nef', '.py'))
        ghost_address = hash160(output)
        print(to_hex_str(ghost_address))
        output, manifest = self.compile_and_save(aux_path)
        aux_address = hash160(output)
        print(to_hex_str(aux_address))

        # when deploying, the contract will mint tokens to the owner
        deploy_event = engine.get_events('Deployed')
        self.assertEqual(1, len(deploy_event))
        self.assertEqual(2, len(deploy_event[0].arguments))

        # add some gas for fees
        add_amount = 10 * 10 ** 8
        engine.add_gas(aux_address, add_amount)

        # pause contract
        fee = self.run_smart_contract(engine, self.CONTRACT_PATH_NEF, 'updatePause', True,
                signer_accounts=[self.OWNER_SCRIPT_HASH],
                expected_result_type=int)

        # should fail because contract is paused
        with self.assertRaises(TestExecutionException, msg=self.ASSERT_RESULTED_FALSE_MSG):
            token = self.run_smart_contract(engine, self.CONTRACT_PATH_NEF, 'mint', 
                    aux_address, self.TOKEN_META, self.LOCK_CONTENT, self.ROYALTIES, None,
                    signer_accounts=[aux_address],
                    expected_result_type=bytes)

        # unpause contract
        fee = self.run_smart_contract(engine, self.CONTRACT_PATH_NEF, 'updatePause', False,
                signer_accounts=[self.OWNER_SCRIPT_HASH],
                expected_result_type=int)

        # mint
        token = self.run_smart_contract(engine, self.CONTRACT_PATH_NEF, 'mint', 
            aux_address, self.TOKEN_META, self.LOCK_CONTENT, self.ROYALTIES, None,
            signer_accounts=[aux_address],
            expected_result_type=bytes)
        self.print_notif(engine.notifications)
Exemplo n.º 7
0
    def test_ghost_burn(self):
        engine = self.prepare_testengine()
        engine.add_contract(self.CONTRACT_PATH_NEF.replace('.py', '.nef'))
        aux_path = self.get_contract_path('test_native', 'auxiliary_contract.py')
        output, manifest = self.compile_and_save(self.CONTRACT_PATH_NEF.replace('.nef', '.py'))
        ghost_address = hash160(output)
        print(to_hex_str(ghost_address))
        output, manifest = self.compile_and_save(aux_path)
        aux_address = hash160(output)
        print(to_hex_str(aux_address))

        # when deploying, the contract will mint tokens to the owner
        deploy_event = engine.get_events('Deployed')
        self.assertEqual(1, len(deploy_event))
        self.assertEqual(2, len(deploy_event[0].arguments))

        # add some gas for fees
        add_amount = 10 * 10 ** 8
        engine.add_gas(aux_address, add_amount)

        # mint
        token = self.run_smart_contract(engine, self.CONTRACT_PATH_NEF, 'mint', 
                aux_address, self.TOKEN_META, self.LOCK_CONTENT, self.ROYALTIES, None,
                signer_accounts=[aux_address],
                expected_result_type=bytes)

        # burn
        burn = self.run_smart_contract(engine, self.CONTRACT_PATH_NEF, 'burn', token,
                signer_accounts=[aux_address],
                expected_result_type=bool)
        print("props: " + str(burn))

        # check balances after
        ghost_balance_after = self.run_smart_contract(engine, self.CONTRACT_PATH_NEF, 'balanceOf', aux_address)
        self.assertEqual(0, ghost_balance_after)
        ghost_supply_after = self.run_smart_contract(engine, self.CONTRACT_PATH_NEF, 'totalSupply')
        self.assertEqual(0, ghost_supply_after)
        self.print_notif(engine.notifications)
Exemplo n.º 8
0
    def test_ghost_onNEP17Payment(self):
        engine = self.prepare_testengine()
        engine.add_contract(self.CONTRACT_PATH_NEF.replace('.py', '.nef'))
        aux_path = self.get_contract_path('test_native', 'auxiliary_contract.py')
        output, manifest = self.compile_and_save(self.CONTRACT_PATH_NEF.replace('.nef', '.py'))
        ghost_address = hash160(output)
        print(to_hex_str(ghost_address))
        output, manifest = self.compile_and_save(aux_path)
        aux_address = hash160(output)
        print(to_hex_str(aux_address))

        # when deploying, the contract will mint tokens to the owner
        deploy_event = engine.get_events('Deployed')
        self.assertEqual(1, len(deploy_event))
        self.assertEqual(2, len(deploy_event[0].arguments))

        # add some gas for fees
        add_amount = 10 * 10 ** 8
        engine.add_gas(aux_address, add_amount)

        # the smart contract will abort if some address other than GAS calls the NEP17 onPayment method
        with self.assertRaises(TestExecutionException, msg=self.ABORTED_CONTRACT_MSG):
            self.run_smart_contract(engine, self.CONTRACT_PATH_NEF, 'onNEP17Payment', aux_address, add_amount, None,
                                    signer_accounts=[aux_address])
Exemplo n.º 9
0
 def to_json(self, path: Union[str, UInt160], method: str,
             *args: Any) -> Dict[str, Any]:
     return {
         'path':
         path if isinstance(path, str) else '',
         'scripthash':
         str(path) if isinstance(path, UInt160) else None,
         'method':
         method,
         'arguments': [contract_parameter_to_json(x) for x in args],
         'storage':
         self._storage.to_json(),
         'contracts': [{
             'nef': contract_path
         } for contract_path in self._contract_paths],
         'signerAccounts':
         [to_hex_str(address) for address in self._accounts],
         'height':
         self.height,
         'blocks': [block.to_json() for block in self.blocks]
     }
Exemplo n.º 10
0
 def __str__(self) -> str:
     """ Convert the data to a human readable format (data is in reverse byte order). """
     return to_hex_str(self._data)
Exemplo n.º 11
0
 def is_valid_identifier(self, item: str) -> bool:
     # valid identifiers are nef path or a representation of the script hash
     return (item == self._nef_path or item == self._script_hash
             or item == to_hex_str(self._script_hash))
Exemplo n.º 12
0
 def __str__(self) -> str:
     return '[{0}] {1}'.format(to_hex_str(self.origin), self._message)
Exemplo n.º 13
0
 def __str__(self) -> str:
     return '[{0}] {1}'.format(to_hex_str(self.origin), self._event_name)
Exemplo n.º 14
0
    def test_ghost_transfer(self):
        engine = self.prepare_testengine()
        engine.add_contract(self.CONTRACT_PATH_NEF.replace('.py', '.nef'))
        aux_path = self.get_contract_path('test_native', 'auxiliary_contract.py')
        output, manifest = self.compile_and_save(self.CONTRACT_PATH_NEF.replace('.nef', '.py'))
        ghost_address = hash160(output)
        print(to_hex_str(ghost_address))
        output, manifest = self.compile_and_save(aux_path)
        aux_address = hash160(output)
        print(to_hex_str(aux_address))

        # when deploying, the contract will mint tokens to the owner
        deploy_event = engine.get_events('Deployed')
        self.assertEqual(1, len(deploy_event))
        self.assertEqual(2, len(deploy_event[0].arguments))

        # add some gas for fees
        add_amount = 10 * 10 ** 8
        engine.add_gas(aux_address, add_amount)

        # mint
        token = self.run_smart_contract(engine, self.CONTRACT_PATH_NEF, 'mint', 
                aux_address, self.TOKEN_META, self.LOCK_CONTENT, self.ROYALTIES, None,
                signer_accounts=[aux_address],
                expected_result_type=bytes)
        properties = self.run_smart_contract(engine, self.CONTRACT_PATH_NEF, 'properties', token)
        print("props: " + str(properties))

        # check balances after
        ghost_amount_after = self.run_smart_contract(engine, GAS_SCRIPT, 'balanceOf', ghost_address)
        gas_aux_after = self.run_smart_contract(engine, GAS_SCRIPT, 'balanceOf', aux_address)
        print("ghost gas amount: " + str(ghost_amount_after))
        print("aux gas amount: " + str(gas_aux_after))
        ghost_balance_after = self.run_smart_contract(engine, self.CONTRACT_PATH_NEF, 'balanceOf', aux_address)
        print("balance nft: " + str(ghost_balance_after))
        ghost_supply_after = self.run_smart_contract(engine, self.CONTRACT_PATH_NEF, 'totalSupply')
        print("supply nft: " + str(ghost_supply_after))
        self.assertEqual(1, ghost_supply_after)

        # check owner before
        ghost_owner_of_before = self.run_smart_contract(engine, self.CONTRACT_PATH_NEF, 'ownerOf', token)
        print("owner of before: " + str(ghost_owner_of_before))

        # transfer
        result = self.run_smart_contract(engine, self.CONTRACT_PATH_NEF, 'transfer', 
                self.OTHER_ACCOUNT_1, token, None,
                signer_accounts=[aux_address],
                expected_result_type=bool)
        self.assertEqual(True, result)

        # check owner after
        ghost_owner_of_after = self.run_smart_contract(engine, self.CONTRACT_PATH_NEF, 'ownerOf', token)
        print("owner of after: " + str(ghost_owner_of_after))
        self.assertEqual(ghost_owner_of_after, self.OTHER_ACCOUNT_1)

        # check balances after
        ghost_balance_after_transfer = self.run_smart_contract(engine, self.CONTRACT_PATH_NEF, 'balanceOf', aux_address)
        ghost_supply_after_transfer = self.run_smart_contract(engine, self.CONTRACT_PATH_NEF, 'totalSupply')
        print("balance nft after transfer: " + str(ghost_balance_after_transfer))
        self.assertEqual(0, ghost_balance_after_transfer)
        self.assertEqual(1, ghost_supply_after_transfer)

        # try to transfer non existing token id
        with self.assertRaises(TestExecutionException, msg=self.ASSERT_RESULTED_FALSE_MSG):
            result = self.run_smart_contract(engine, self.CONTRACT_PATH_NEF, 'transfer', 
                    self.OTHER_ACCOUNT_1, bytes('thisisanonexistingtoken', 'utf-8'), None,
                    signer_accounts=[aux_address],
                    expected_result_type=bool)

        self.print_notif(engine.notifications)
Exemplo n.º 15
0
    def test_ghost_gas_cost(self):
        engine = self.prepare_testengine()
        engine.add_contract(self.CONTRACT_PATH_NEF.replace('.py', '.nef'))
        aux_path = self.get_contract_path('test_native', 'auxiliary_contract.py')
        output, manifest = self.compile_and_save(self.CONTRACT_PATH_NEF.replace('.nef', '.py'))
        ghost_address = hash160(output)
        print(to_hex_str(ghost_address))
        output, manifest = self.compile_and_save(aux_path)
        aux_address = hash160(output)
        print(to_hex_str(aux_address))

        # add some gas for fees
        add_amount = 10 * 10 ** 8
        engine.add_gas(aux_address, add_amount)

        # mint token with no meta, no lock content, no royalties
        token = self.run_smart_contract(engine, self.CONTRACT_PATH_NEF, 'mint', 
            aux_address, bytes(1), bytes(0), bytes(0), None,
            signer_accounts=[aux_address],
            expected_result_type=bytes)

        gasConsumed = str(int(engine.gas_consumed) / 10 ** 8)
        print("token with no meta, no lock content, no royalties: " + gasConsumed + " GAS")

        # mint token with meta, no lock content, no royalties
        token = self.run_smart_contract(engine, self.CONTRACT_PATH_NEF, 'mint', 
            aux_address, self.TOKEN_META, bytes(0), bytes(0), None,
            signer_accounts=[aux_address],
            expected_result_type=bytes)

        gasConsumed = str(int(engine.gas_consumed) / 10 ** 8)
        print("token with meta, no lock content, no royalties: " + gasConsumed + " GAS")

        # mint token with meta, lock content, no royalties
        token = self.run_smart_contract(engine, self.CONTRACT_PATH_NEF, 'mint', 
            aux_address, self.TOKEN_META, self.LOCK_CONTENT, bytes(0), None,
            signer_accounts=[aux_address],
            expected_result_type=bytes)

        gasConsumed = str(int(engine.gas_consumed) / 10 ** 8)
        print("token with meta, lock content, no royalties: " + gasConsumed + " GAS")

        # mint token with meta, no lock content, royalties
        token = self.run_smart_contract(engine, self.CONTRACT_PATH_NEF, 'mint', 
            aux_address, self.TOKEN_META, bytes(0), self.ROYALTIES, None,
            signer_accounts=[aux_address],
            expected_result_type=bytes)

        gasConsumed = str(int(engine.gas_consumed) / 10 ** 8)
        print("token with meta, no lock content, royalties: " + gasConsumed + " GAS")

        # mint token with meta, lock content, royalties
        token = self.run_smart_contract(engine, self.CONTRACT_PATH_NEF, 'mint', 
            aux_address, self.TOKEN_META, self.LOCK_CONTENT, self.ROYALTIES, None,
            signer_accounts=[aux_address],
            expected_result_type=bytes)

        gasConsumed = str(int(engine.gas_consumed) / 10 ** 8)
        print("token with meta, lock content, royalties: " + gasConsumed + " GAS")

        tokenMeta = bytes('{ "name": "GHOST3", "description": "A ghost shows up", "image": "{some image URI}", "name": "GHOST3", "description": "A ghost shows up", "image": "{some image URI}", "name": "GHOST3", "description": "A ghost shows up", "image": "{some image URI}", "name": "GHOST3", "description": "A ghost shows up", "image": "{some image URI}", "tokenURI": "{some URI}" }', 'utf-8')

        lockedContent = bytes('123456789101234567891012345678910123456789101234567891012345678910123456789101234567891012345678910123456789101234567891012345678910123456789101234567891012345678910123456789101234567891012345678910', 'utf-8')

        royalties = bytes('[{"address": "someaddress", "value": 20}, {"address": "someaddress2", "value": 30},{"address": "someaddress", "value": 20}, {"address": "someaddress2", "value": 30},{"address": "someaddress", "value": 20}, {"address": "someaddress2", "value": 30}]', 'utf-8')

        # mint high end token
        token = self.run_smart_contract(engine, self.CONTRACT_PATH_NEF, 'mint', 
            aux_address, tokenMeta, lockedContent, royalties, None,
            signer_accounts=[aux_address],
            expected_result_type=bytes)
            
        gasConsumed = str(int(engine.gas_consumed) / 10 ** 8)
        print("token with heavy meta, heavy lock content, heavy royalties: " + gasConsumed + " GAS")

        # get locked content
        content = self.run_smart_contract(engine, self.CONTRACT_PATH_NEF, 'getLockedContent', token,
                signer_accounts=[aux_address],
                expected_result_type=bytes)
            
        gasConsumed = str(int(engine.gas_consumed) / 10 ** 8)
        print("get locked content: " + gasConsumed + " GAS")

        # burn token
        burn = self.run_smart_contract(engine, self.CONTRACT_PATH_NEF, 'burn', token,
            signer_accounts=[aux_address],
            expected_result_type=bool)

        gasConsumed = str(int(engine.gas_consumed) / 10 ** 8)
        print("burn: " + gasConsumed + " GAS")