Пример #1
0
def token_send_blog(wallet, args):
    if len(args) != 4:
        print(
            "please provide a token symbol, from address, to address, and amount sb"
        )
        return False
    contract = args[0]
    send_from = args[1]
    send_to = args[2]
    amount = 0

    # allowance = token_get_allowance(wallet, args[:-1], verbose=False)

    if True:

        invoke_args = [
            contract, 'output',
            [
                parse_param(send_from, wallet),
                parse_param(send_to, wallet),
                parse_param(amount)
            ]
        ]
        print(invoke_args)
        tx, fee, results, num_ops = TestInvokeContract(wallet, invoke_args,
                                                       None, True, send_from)

        if tx is not None and results is not None and len(results) > 0:

            if results[0].GetBigInteger() == 1:

                return InvokeContract(wallet, tx, fee)

    return False
Пример #2
0
    def Transfer(self, wallet, from_addr, to_addr, amount, tx_attributes=None):
        """
        Transfer a specified amount of the NEP5Token to another address.

        Args:
            wallet (neo.Wallets.Wallet): a wallet instance.
            from_addr (str): public address of the account to transfer the given amount from.
            to_addr (str): public address of the account to transfer the given amount to.
            amount (int): quantity to send.
            tx_attributes (list): a list of TransactionAtribute objects.

        Returns:
            tuple:
                InvocationTransaction: the transaction.
                int: the transaction fee.
                list: the neo VM evaluationstack results.
        """
        if not tx_attributes:
            tx_attributes = []

        sb = ScriptBuilder()
        sb.EmitAppCallWithOperationAndArgs(self.ScriptHash, 'transfer',
                                           [parse_param(from_addr, wallet), parse_param(to_addr, wallet),
                                            parse_param(amount)])

        tx, fee, results, num_ops = test_invoke(sb.ToArray(), wallet, [], from_addr=from_addr, invoke_attrs=tx_attributes)

        return tx, fee, results
Пример #3
0
    def GetBalance(self, wallet, address, as_string=False):

        if type(address) is UInt160:
            address = Crypto.ToAddress(address)

        invoke_args = [
            self.ScriptHash.ToString(),
            parse_param('balanceOf'), [parse_param(address)]
        ]
        tx, fee, balanceResults, num_ops = TestInvokeContract(
            wallet, invoke_args, None, False)

        try:
            val = balanceResults[0].GetBigInteger()
            precision_divisor = pow(10, self.decimals)
            balance = Decimal(val) / Decimal(precision_divisor)
            if as_string:
                formatter_str = '.%sf' % self.decimals
                balance_str = format(balance, formatter_str)
                return balance_str
            return balance
        except Exception as e:
            logger.error("could not get balance: %s " % e)
            traceback.print_stack()

        return 0
Пример #4
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
Пример #5
0
def GatherLoadedContractParams(args, script):
    if len(args) < 4:
        raise Exception(
            "please specify contract properties like {params} {return_type} {needs_storage} {needs_dynamic_invoke}"
        )
    params = parse_param(args[0], ignore_int=True, prefer_hex=False)

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

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

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

    contract_properties = 0

    if needs_storage:
        contract_properties += ContractPropertyState.HasStorage

    if needs_dynamic_invoke:
        contract_properties += ContractPropertyState.HasDynamicInvoke

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

    return out
Пример #6
0
    def test_NFT_3_mint(self):

        output = Compiler.instance().load('nft_template.py').default
        out = output.write()

        TestContract.dispatched_events = []

	# mint another token
        owner = bytearray(TOKEN_CONTRACT_OWNER)
        tx, results, total_ops, engine = TestBuild(out, ['mintToken', parse_param([owner,2,'token2ROData','https://example.com/images/2.png','token2ROData'])], self.GetWallet1(), '0710', '05')
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].GetBoolean(), True)

        # it should dispatch an event
        self.assertEqual(len(TestContract.dispatched_events), 8)
        evt = TestContract.dispatched_events[0]
        self.assertIsInstance(evt, NotifyEvent)
        self.assertEqual(evt.addr_to, self.wallet_1_script_hash)

        # now the total circulation should be bigger
        tx, results, total_ops, engine = TestBuild(out, ['totalSupply', '[]'], self.GetWallet1(), '0710', '05')
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].GetBigInteger(), 2)

	# trying to mint a token with an existing token ID should fail
        owner = bytearray(TOKEN_CONTRACT_OWNER)
        tx, results, total_ops, engine = TestBuild(out, ['mintToken', parse_param([owner,2,'token2ROData','https://example.com/images/2.png','token2ROData'])], self.GetWallet1(), '0710', '05')
        self.assertEqual(len(results), 0)
Пример #7
0
    def test_NFT_1(self):

        output = Compiler.instance().load('nft_template.py').default
        out = output.write()

        tx, results, total_ops, engine = TestBuild(out, ['name', '[]'], self.GetWallet1(), '0710', '05')
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].GetString(), TOKEN_NAME)

        tx, results, total_ops, engine = TestBuild(out, ['symbol', '[]'], self.GetWallet1(), '0710', '05')
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].GetString(), TOKEN_SYMBOL)

        tx, results, total_ops, engine = TestBuild(out, ['decimals', '[]'], self.GetWallet1(), '0710', '05')
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].GetBigInteger(), TOKEN_DECIMALS)

        tx, results, total_ops, engine = TestBuild(out, ['nonexistentmethod', '[]'], self.GetWallet1(), '0710', '05')
        self.assertEqual(len(results), 0)

	# mint a token
        owner = bytearray(TOKEN_CONTRACT_OWNER)
        tx, results, total_ops, engine = TestBuild(out, ['mintToken', parse_param([owner,1,'token1ROData','https://example.com/images/1.png','token1ROData'])], self.GetWallet1(), '0710', '05')
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].GetBoolean(), True)

        # now circulation should be equal to 1
        tx, results, total_ops, engine = TestBuild(out, ['totalSupply', '[]'], self.GetWallet1(), '0710', '05')
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].GetBigInteger(), 1)

        # now the owner should have a balance of 1
        tx, results, total_ops, engine = TestBuild(out, ['balanceOf', parse_param([bytearray(TOKEN_CONTRACT_OWNER)])], self.GetWallet1(), '0710', '05')
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].GetBigInteger(), 1)
Пример #8
0
    def Query(self, wallet):

        if self.name is not None:
            # don't query twice
            return

        invoke_args = [self.ScriptHash.ToString(), parse_param('name'), []]
        invoke_args2 = [self.ScriptHash.ToString(), parse_param('symbol'), []]
        invoke_args3 = [
            self.ScriptHash.ToString(),
            parse_param('decimals'), []
        ]
        tx, fee, nameResults, num_ops = TestInvokeContract(
            wallet, invoke_args, None, False)
        tx, fee, symbolResults, num_ops = TestInvokeContract(
            wallet, invoke_args2, None, False)
        tx, fee, decimalResults, num_ops = TestInvokeContract(
            wallet, invoke_args3, None, False)

        try:

            self.name = nameResults[0].GetString()
            self.symbol = symbolResults[0].GetString()
            self.decimals = decimalResults[0].GetBigInteger()
            return True
        except Exception as e:
            logger.error("could not query token %s " % e)

        return False
Пример #9
0
def GatherLoadedContractParams(args, script):
    if len(args) < 5:
        raise Exception("please specify contract properties like {needs_storage} {needs_dynamic_invoke} {is_payable} {params} {return_type}")
    params = parse_param(args[3], ignore_int=True, prefer_hex=False)

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

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

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

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

    contract_properties = 0

    if needs_storage:
        contract_properties += ContractPropertyState.HasStorage

    if needs_dynamic_invoke:
        contract_properties += ContractPropertyState.HasDynamicInvoke

    if is_payable:
        contract_properties += ContractPropertyState.Payable

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

    return out
Пример #10
0
    def TransferFrom(self, wallet, from_addr, to_addr, amount):
        """
        Transfer a specified amount of a token from the wallet specified in the `from_addr` to the `to_addr`
        if the originator `wallet` has been approved to do so.

        Args:
            wallet (neo.Wallets.Wallet): a wallet instance.
            from_addr (str): public address of the account to transfer the given amount from.
            to_addr (str): public address of the account to transfer the given amount to.
            amount (int): quantity to send.

        Returns:
            tuple:
                InvocationTransaction: the transaction.
                int: the transaction fee.
                list: the neo VM evaluation stack results.
        """
        invoke_args = [
            self.ScriptHash.ToString(), 'transferFrom',
            [
                parse_param(from_addr, wallet),
                parse_param(to_addr, wallet),
                parse_param(amount)
            ]
        ]

        tx, fee, results, num_ops = TestInvokeContract(wallet, invoke_args,
                                                       None, True)

        return tx, fee, results
Пример #11
0
    def Approve(self, wallet, owner_addr, requestor_addr, amount):
        """
        Approve the `requestor_addr` account to transfer `amount` of tokens from the `owner_addr` acount.

        Args:
            wallet (neo.Wallets.Wallet): a wallet instance.
            owner_addr (str): public address of the account to transfer the given amount from.
            requestor_addr (str): public address of the account that requests the transfer.
            amount (int): quantity to send.

        Returns:
            tuple:
                InvocationTransaction: the transaction.
                int: the transaction fee.
                list: the neo VM evaluation stack results.
        """
        invoke_args = [
            self.ScriptHash.ToString(), 'approve',
            [
                parse_param(owner_addr, wallet),
                parse_param(requestor_addr, wallet),
                parse_param(amount)
            ]
        ]

        tx, fee, results, num_ops = TestInvokeContract(wallet, invoke_args,
                                                       None, True)

        return tx, fee, results
Пример #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 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 = bytearray(binascii.unhexlify(str(args[2]).encode('utf-8')))

    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
Пример #14
0
    def test_2_SmartNEP5(self):

        timestamp = round(time.time())
        test_neo_acc = 'NEO'+ str(timestamp)[-8:]
        test_neo_acc2 = 'NEO'+ str(timestamp-10000)[-8:]

        print('=========== NA =============')
        output = Compiler.instance().load('./nasc.py').default
        out = output.write()

        print('===== init =====')
        tx, results, total_ops, engine = TestBuild(out, ['init', '[]'], self.GetWallet1(), '0710', '05')
        self.assertEqual(len(results), 1)
        self.assertIn(results[0].GetString() ,['NASC initialized.', 'Uknown operation'])
        
        print('===== test =====')
        tx, results, total_ops, engine = TestBuild(out, ['na_test', '[]'], self.GetWallet1(), '0710', '05')
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].GetString() ,'NASC is up!')

        tx, results, total_ops, engine = TestBuild(out, ['na_register', parse_param([test_neo_acc, self.wallet_1_script_hash.Data, 4, self.wallet_1_script_hash.Data, 1519912704])], self.GetWallet1(), '0710', '05')
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].GetString() , 'Alias registered: '+ test_neo_acc)

        tx, results, total_ops, engine = TestBuild(out, ['smart_balanceOf', parse_param([test_neo_acc])], self.GetWallet1(), '0710', '05')
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].GetBigInteger() , 10000)

        tx, results, total_ops, engine = TestBuild(out, ['na_register', parse_param([test_neo_acc2, self.wallet_3_script_hash.Data, 4, self.wallet_3_script_hash.Data, 1519912704])], self.GetWallet3(), '0710', '05')
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].GetString() , 'Alias registered: '+ test_neo_acc2)

        print('===== transfer =====')
        tx, results, total_ops, engine = TestBuild(out, ['smart_transfer', parse_param([test_neo_acc, test_neo_acc2, 500])], self.GetWallet1(), '0710', '05')
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].GetString(), 'Transfer completed.')

        tx, results, total_ops, engine = TestBuild(out, ['smart_balanceOf', parse_param([test_neo_acc2])], self.GetWallet1(), '0710', '05')
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].GetBigInteger() , 500)

        print('===== aprove =====')
        tx, results, total_ops, engine = TestBuild(out, ['smart_approve', parse_param([test_neo_acc, test_neo_acc2, 50])], self.GetWallet1(), '0710', '05')
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].GetByteArray(), b'Spender can withdraw (from your address): 2')

        print('===== allowance =====')
        tx, results, total_ops, engine = TestBuild(out, ['smart_allowance', parse_param([test_neo_acc, test_neo_acc2])], self.GetWallet1(), '0710', '05')
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].GetByteArray(), b'Spender can withdraw: 2')

        print('===== transfeFrom =====')
        tx, results, total_ops, engine = TestBuild(out, ['smart_transferFrom', parse_param([test_neo_acc2, test_neo_acc, test_neo_acc2, 50])], self.GetWallet3(), '0710', '05')
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].GetString(), 'TransferFrom completed.')

        print('===== balanceOf =====')
        tx, results, total_ops, engine = TestBuild(out, ['smart_balanceOf', parse_param([test_neo_acc2])], self.GetWallet1(), '0710', '05')
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].GetBigInteger() , 550)
Пример #15
0
    def test_ICOTemplate_5_mint(self):

        output = Compiler.instance().load(
            '%s/boa_test/example/demo/ICO_Template.py' %
            TestContract.dirname).default
        out = output.write()

        # register an address
        tx, results, total_ops, engine = TestBuild(out, [
            'crowdsale_register',
            parse_param([self.wallet_3_script_hash.Data])
        ], self.GetWallet1(), '0705', '05')
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].GetBigInteger(), 1)

        TestContract.dispatched_events = []

        # test mint tokens, this should return true
        tx, results, total_ops, engine = TestBuild(
            out, ['mintTokens', '[]', '--attach-neo=10'], self.GetWallet3(),
            '0705', '05')
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].GetBoolean(), True)

        # it should dispatch an event
        self.assertEqual(len(TestContract.dispatched_events), 1)
        evt = TestContract.dispatched_events[0]
        self.assertIsInstance(evt, NotifyEvent)
        self.assertEqual(evt.amount, 10 * TOKENS_PER_NEO)
        self.assertEqual(evt.addr_to, self.wallet_3_script_hash)

        # test mint tokens again, this should be false since you can't do it twice
        tx, results, total_ops, engine = TestBuild(
            out, ['mintTokens', '[]', '--attach-neo=10'], self.GetWallet3(),
            '0705', '05')
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].GetBoolean(), False)

        # now the minter should have a balance
        tx, results, total_ops, engine = TestBuild(
            out, ['balanceOf',
                  parse_param([self.wallet_3_script_hash.Data])],
            self.GetWallet1(), '0705', '05')
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].GetBigInteger(), 10 * TOKENS_PER_NEO)

        # now the total circulation should be bigger
        tx, results, total_ops, engine = TestBuild(out, ['totalSupply', '[]'],
                                                   self.GetWallet1(), '0705',
                                                   '05')
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].GetBigInteger(),
                         (10 * TOKENS_PER_NEO) + TOKEN_INITIAL_AMOUNT)
Пример #16
0
    def Allowance(self, wallet, owner_addr, requestor_addr):
        invoke_args = [
            self.ScriptHash.ToString(), 'allowance',
            [
                parse_param(owner_addr, wallet),
                parse_param(requestor_addr, wallet)
            ]
        ]

        tx, fee, results, num_ops = TestInvokeContract(wallet, invoke_args,
                                                       None, True)

        return tx, fee, results
Пример #17
0
    def TransferFrom(self, wallet, from_addr, to_addr, amount):
        invoke_args = [
            self.ScriptHash.ToString(), 'transferFrom',
            [
                parse_param(from_addr),
                parse_param(to_addr),
                parse_param(amount)
            ]
        ]

        tx, fee, results, num_ops = TestInvokeContract(wallet, invoke_args,
                                                       None, True)

        return tx, fee, results
Пример #18
0
    async def process_testinvoke_job(self):
        job_args = self.parser.parseString(self.operation + " " + str(self.job))
        job_args = job_args[0:]

        if len(job_args) != 2:
            self.logger.error('ERROR! must have only 2 args (operation, params). skipping! %s', job_args)
            self.job = None
            self.process_job()
            return

        operation_params = parse_param(job_args[1])
        if len(operation_params) != self.operation_args_array_length:
            self.logger.error('ERROR! must have exactly %d operation args, not %d. skipping! %s', self.operation_args_array_length, len(operation_params), job_args)
            self.job = None
            self.process_job()
            return

        args = [self.smart_contract_hash] + job_args
        self.logger.debug('processing job: %s', args)
        result = await self.test_invoke(args, self.expected_result_count, self.test_only, self.from_addr)

        if not result:
            # transaction failed? wallet probably out-of-sync (insufficient funds) so reload it
            self.wallet_needs_recovery = True
        else:
            # this job has been invoked, so clear it out. on to the next.
            self.job = None
            if self.test_only:
                # when testing but not relaying transactions, we just continue to the next job
                self.jobs_processed += 1
                self.process_job()
            else:
                # transaction successfully relayed? then let's set the tx Hash that we're waiting for
                self.tx_processing = result.Hash
Пример #19
0
    def GetBalance(self, wallet, address, as_string=False):
        """
        Get the token balance.

        Args:
            wallet (neo.Wallets.Wallet): a wallet instance.
            address (str): public address of the account to get the token balance of.
            as_string (bool): whether the return value should be a string. Default is False, returning an integer.

        Returns:
            int/str: token balance value as int (default), token balanace as string if `as_string` is set to True. 0 if balance retrieval failed.
        """
        addr = parse_param(address, wallet)
        if isinstance(addr, UInt160):
            addr = addr.Data
        sb = ScriptBuilder()
        sb.EmitAppCallWithOperationAndArgs(self.ScriptHash, 'balanceOf', [addr])

        tx, fee, results, num_ops = test_invoke(sb.ToArray(), wallet, [])

        try:
            val = results[0].GetBigInteger()
            precision_divisor = pow(10, self.decimals)
            balance = Decimal(val) / Decimal(precision_divisor)
            if as_string:
                formatter_str = '.%sf' % self.decimals
                balance_str = format(balance, formatter_str)
                return balance_str
            return balance
        except Exception as e:
            logger.error("could not get balance: %s " % e)
            traceback.print_stack()

        return 0
Пример #20
0
    def GetBalance(self, wallet, address, as_string=False):
        """
        Get the token balance.

        Args:
            wallet (neo.Wallets.Wallet): a wallet instance.
            address (str): public address of the account to get the token balance of.
            as_string (bool): whether the return value should be a string. Default is False, returning an integer.

        Returns:
            int/str: token balance value as int (default), token balanace as string if `as_string` is set to True. 0 if balance retrieval failed.
        """
        addr = parse_param(address, wallet)
        if isinstance(addr, UInt160):
            addr = addr.Data
        sb = ScriptBuilder()
        sb.EmitAppCallWithOperationAndArgs(self.ScriptHash, 'balanceOf', [addr])

        tx, fee, results, num_ops = test_invoke(sb.ToArray(), wallet, [])

        try:
            val = results[0].GetBigInteger()
            precision_divisor = pow(10, self.decimals)
            balance = Decimal(val) / Decimal(precision_divisor)
            if as_string:
                formatter_str = '.%sf' % self.decimals
                balance_str = format(balance, formatter_str)
                return balance_str
            return balance
        except Exception as e:
            logger.error("could not get balance: %s " % e)
            traceback.print_stack()

        return 0
Пример #21
0
    def test_ICOTemplate_3_KYC(self):

        output = Compiler.instance().load('%s/ico_template.py' % TestContract.dirname).default
        out = output.write()
        print(output.to_s())
        # now transfer tokens to wallet 2

        TestContract.dispatched_events = []

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

        # Try to register as a non owner
        tx, results, total_ops, engine = TestBuild(out, ['crowdsale_register', parse_param([self.wallet_3_script_hash.Data])], self.GetWallet3(), '0705', '05')
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].GetBoolean(), False)

        # Get status of non registered address
        tx, results, total_ops, engine = TestBuild(out, ['crowdsale_status', parse_param([self.wallet_3_script_hash.Data])], self.GetWallet3(), '0705', '05')
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].GetBoolean(), False)

        TestContract.dispatched_events = []

        # register an address
        tx, results, total_ops, engine = TestBuild(out, ['crowdsale_register', parse_param([self.wallet_3_script_hash.Data])], self.GetWallet1(), '0705', '05')
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].GetBigInteger(), 1)

        # it should dispatch an event
        self.assertEqual(len(TestContract.dispatched_events), 1)
        evt = TestContract.dispatched_events[0]
        # self.assertEqual(evt.event_payload[0], b'kyc_registration')

        # register 2 addresses at once
        tx, results, total_ops, engine = TestBuild(out, ['crowdsale_register', parse_param([self.wallet_3_script_hash.Data, self.wallet_2_script_hash.Data])], self.GetWallet1(), '0705', '05')
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].GetBigInteger(), 2)

        # now check reg status
        tx, results, total_ops, engine = TestBuild(out, ['crowdsale_status', parse_param([self.wallet_3_script_hash.Data])], self.GetWallet3(), '0705', '05')
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].GetBoolean(), True)
Пример #22
0
    def test_ICOTemplate_2(self):

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

        # now transfer tokens to wallet 2

        TestContract.dispatched_events = []

        test_transfer_amount = 2400000001
        tx, results, total_ops, engine = TestBuild(out, ['transfer', parse_param([bytearray(TOKEN_OWNER), self.wallet_2_script_hash.Data, test_transfer_amount])], self.GetWallet1(), '0705', '05')
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].GetBoolean(), True)

        self.assertEqual(len(TestContract.dispatched_events), 1)
        evt = TestContract.dispatched_events[0]
        self.assertIsInstance(evt, NotifyEvent)
        self.assertEqual(evt.addr_from.Data, bytearray(TOKEN_OWNER))
        self.assertEqual(evt.addr_to, self.wallet_2_script_hash)
        self.assertEqual(evt.amount, test_transfer_amount)

        # now get balance of wallet 2
        tx, results, total_ops, engine = TestBuild(out, ['balanceOf', parse_param([self.wallet_2_script_hash.Data])], self.GetWallet1(), '0705', '05')
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].GetBigInteger(), test_transfer_amount)

        # now the owner should have less
        tx, results, total_ops, engine = TestBuild(out, ['balanceOf', parse_param([bytearray(TOKEN_OWNER)])], self.GetWallet1(), '0705', '05')
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].GetBigInteger(), TOKEN_INITIAL_AMOUNT - test_transfer_amount)

        # now this transfer should fail
        tx, results, total_ops, engine = TestBuild(out, ['transfer', parse_param([bytearray(TOKEN_OWNER), self.wallet_2_script_hash.Data, TOKEN_INITIAL_AMOUNT])], self.GetWallet1(), '0705', '05')
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].GetBoolean(), False)

        # this transfer should fail because it is not signed by the 'from' address
        tx, results, total_ops, engine = TestBuild(out, ['transfer', parse_param([bytearray(TOKEN_OWNER), self.wallet_2_script_hash.Data, 10000])], self.GetWallet3(), '0705', '05')
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].GetBoolean(), False)

        # now this transfer should fail, this is from address with no tokens
        tx, results, total_ops, engine = TestBuild(out, ['transfer', parse_param([self.wallet_3_script_hash.Data, self.wallet_2_script_hash.Data, 1000])], self.GetWallet3(), '0705', '05')
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].GetBoolean(), False)

        # get balance of bad data
        tx, results, total_ops, engine = TestBuild(out, ['balanceOf', parse_param(['abc'])], self.GetWallet1(), '0705', '05')
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].GetBigInteger(), 0)

        # get balance no params
        tx, results, total_ops, engine = TestBuild(out, ['balanceOf', parse_param([])], self.GetWallet1(), '0705', '05')
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].GetBoolean(), False)
Пример #23
0
def RedeemWithdraw(prompter, wallet, args):
    """
    withdraw {CONTRACT_ADDR} {ASSET} {TO_ADDR} {AMOUNT}
    """
    if not wallet:
        print("please open a wallet")
        return

    withdrawal_tx = construct_withdrawal_tx(wallet, args)

    if withdrawal_tx:

        outputs = withdrawal_tx.outputs
        contract_hash = wallet.ToScriptHash(args[0]).ToString()
        to_addr = wallet.ToScriptHash(args[2])
        invoke_args = [
            contract_hash,
            parse_param('getBalance'), [to_addr.Data]
        ]
        print("invoke args... %s " % invoke_args)
        tx, fee, results, num_ops = TestInvokeContract(wallet, invoke_args,
                                                       None, False)
        print("tx is %s %s" % (withdrawal_tx.outputs, withdrawal_tx.inputs))

        if tx is not None and results is not None:
            print(
                "\n-------------------------------------------------------------------------------------------------------------------------------------"
            )
            print("Test Withdraw successful")
            print("Total operations: %s " % num_ops)
            print("Results %s " % [str(item) for item in results])
            print("Withdraw gas cost: %s " % (tx.Gas.value / Fixed8.D))
            print("Withdraw Fee: %s " % (fee.value / Fixed8.D))
            print(
                "-------------------------------------------------------------------------------------------------------------------------------------\n"
            )
            print("Enter your password to complete this withdrawal")

            passwd = prompt("[Password]> ", is_password=True)

            if not wallet.ValidatePassword(passwd):
                print("incorrect password")
                return
            withdrawal_tx.scripts = []
            withdrawal_tx.Script = tx.Script
            withdrawal_tx.outputs = outputs

            #            tx.scripts = []
            #            tx.inputs = withdrawal_tx.inputs
            #            tx.outputs = withdrawal_tx.outputs
            result = InvokeWithdrawTx(wallet, withdrawal_tx, contract_hash)

            return result
        else:
            print("Error testing contract invoke")
            return
Пример #24
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}")
Пример #25
0
    def CrowdsaleRegister(self, wallet, register_addresses):

        invoke_args = [
            self.ScriptHash.ToString(), 'crowdsale_register',
            [parse_param(p, wallet) for p in register_addresses]
        ]

        tx, fee, results, num_ops = TestInvokeContract(wallet, invoke_args,
                                                       None, True)

        return tx, fee, results
Пример #26
0
def GatherLoadedContractParams(args, script):

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

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

    return_type = parse_param(args[1], 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[2]))

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

    return out
Пример #27
0
    def test_ICOTemplate_7_reserve(self):
        output = Compiler.instance().load('%s/ico_template.py' % TestContract.dirname).default
        out = output.write()

        burn_amt = 1000000000 * 100000000
        reserve_amt = burn_amt * 2
        reserve_amt_too_many = burn_amt * 4
        
        tx, results, total_ops, engine = TestBuild(out, ['balanceOf', parse_param([self.wallet_1_script_hash.Data])], self.GetWallet1(), '0705', '05')
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].GetBigInteger(), 599999997599999999)

        # reserve for private sale fails CheckWitness
        tx, results, total_ops, engine = TestBuild(out, ['reserve_private', '[%s]' % reserve_amt], self.GetWallet2(), '0705', '05')
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].GetBoolean(), False)

        # cannot reserve too many
        tx, results, total_ops, engine = TestBuild(out, ['reserve_private', '[%s]' % reserve_amt_too_many], self.GetWallet1(), '0705', '05')
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].GetBoolean(), False)

        # reserve success
        tx, results, total_ops, engine = TestBuild(out, ['reserve_private', '[%s]' % reserve_amt], self.GetWallet1(), '0705', '05')
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].GetBoolean(), True)

        tx, results, total_ops, engine = TestBuild(out, ['balanceOf', parse_param([self.wallet_1_script_hash.Data])], self.GetWallet1(), '0705', '05')
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].GetBigInteger(), 599999997599999999 + reserve_amt)

        # tokens available for sale
        tx, results, total_ops, engine = TestBuild(out, ['crowdsale_available', '[]'], self.GetWallet2(), '0705', '05')
        self.assertEqual(len(results), 1)
        # self.assertEqual(results[0].GetBigInteger(), 4000000000 * 100000000 - 54000000000000 - burn_amt - reserve_amt)
        self.assertEqual(results[0].GetBigInteger(), 4000000000 * 100000000 - 50000000000000 - burn_amt - reserve_amt)

        # can reserve twice
        tx, results, total_ops, engine = TestBuild(out, ['reserve_private', '[%s]' % 10000], self.GetWallet1(), '0705', '05')
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].GetBoolean(), True)
Пример #28
0
    def test_ICOTemplate_1(self):

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

        tx, results, total_ops, engine = TestBuild(out, ['name', '[]'], self.GetWallet1(), '0705', '05')
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].GetString(), TOKEN_NAME)

        tx, results, total_ops, engine = TestBuild(out, ['symbol', '[]'], self.GetWallet1(), '0705', '05')
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].GetString(), TOKEN_SYMBOL)

        tx, results, total_ops, engine = TestBuild(out, ['decimals', '[]'], self.GetWallet1(), '0705', '05')
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].GetBigInteger(), TOKEN_DECIMALS)

        tx, results, total_ops, engine = TestBuild(out, ['totalSupply', '[]'], self.GetWallet1(), '0705', '05')
        self.assertEqual(len(results), 1)
        # self.assertEqual(results[0].GetBigInteger(), 0)
        # total supply shall be 10b
        self.assertEqual(results[0].GetBigInteger(), 1000000000000000000)

        tx, results, total_ops, engine = TestBuild(out, ['nonexistentmethod', '[]'], self.GetWallet1(), '0705', '05')
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].GetString(), 'unknown operation')

        # deploy with wallet 2 should fail CheckWitness
        tx, results, total_ops, engine = TestBuild(out, ['deploy', '[]'], self.GetWallet2(), '0705', '05')
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].GetBoolean(), False)

        tx, results, total_ops, engine = TestBuild(out, ['deploy', '[]'], self.GetWallet1(), '0705', '05')
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].GetBoolean(), True)

        # second time, it should already be deployed and return false
        tx, results, total_ops, engine = TestBuild(out, ['deploy', '[]'], self.GetWallet1(), '0705', '05')
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].GetBoolean(), False)

        # now total supply should be equal to the initial owner amount
        tx, results, total_ops, engine = TestBuild(out, ['totalSupply', '[]'], self.GetWallet1(), '0705', '05')
        self.assertEqual(len(results), 1)
        # self.assertEqual(results[0].GetBigInteger(), TOKEN_INITIAL_AMOUNT)
        # by new definition, totalSupply shall be TOKEN_TOTAL_SUPPLY
        self.assertEqual(results[0].GetBigInteger(), TOKEN_TOTAL_SUPPLY)

        # now the owner should have a balance of the TOKEN_INITIAL_AMOUNT
        tx, results, total_ops, engine = TestBuild(out, ['balanceOf', parse_param([bytearray(TOKEN_OWNER)])], self.GetWallet1(), '0705', '05')
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].GetBigInteger(), TOKEN_INITIAL_AMOUNT)
Пример #29
0
    def Allowance(self, wallet, owner_addr, requestor_addr):
        """
        Return the amount of tokens that the `requestor_addr` account can transfer from the `owner_addr` account.

        Args:
            wallet (neo.Wallets.Wallet): a wallet instance.
            owner_addr (str): public address of the account to transfer the given amount from.
            requestor_addr (str): public address of the account that requests the transfer.

        Returns:
            tuple:
                InvocationTransaction: the transaction.
                int: the transaction fee.
                list: the neo VM evaluation stack results.
        """
        invoke_args = [self.ScriptHash.ToString(), 'allowance',
                       [parse_param(owner_addr, wallet), parse_param(requestor_addr, wallet)]]

        tx, fee, results, num_ops = TestInvokeContract(wallet, invoke_args, None, True)

        return tx, fee, results
Пример #30
0
    def test_ICOTemplate_3_personal_cap(self):

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

        # check whitelist cap
        tx, results, total_ops, engine = TestBuild(out, [
            'get_exchangeable_amount',
            parse_param([
                self.wallet_3_script_hash.Data,
                self.WHITELIST_SALE_PERSONAL_CAP + 1, self.now_in_test
            ])
        ], self.GetWallet1(), '0705', '05')
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].GetBigInteger(), 0)

        # check presale cap
        tx, results, total_ops, engine = TestBuild(out, [
            'get_exchangeable_amount',
            parse_param([
                self.wallet_3_script_hash.Data, self.PRESALE_PERSONAL_CAP + 1,
                self.now_in_test + 86400 * 2
            ])
        ], self.GetWallet1(), '0705', '05')
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].GetBigInteger(), 0)

        # check crowdsale cap
        tx, results, total_ops, engine = TestBuild(out, [
            'get_exchangeable_amount',
            parse_param([
                self.wallet_3_script_hash.Data,
                self.CROWDSALE_PERSONAL_CAP + 1, self.now_in_test + 86400 * 4
            ])
        ], self.GetWallet1(), '0705', '05')
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].GetBigInteger(), 0)
Пример #31
0
    def TransferFrom(self, wallet, from_addr, to_addr, amount):
        """
        Transfer a specified amount of a token from the wallet specified in the `from_addr` to the `to_addr`
        if the originator `wallet` has been approved to do so.

        Args:
            wallet (neo.Wallets.Wallet): a wallet instance.
            from_addr (str): public address of the account to transfer the given amount from.
            to_addr (str): public address of the account to transfer the given amount to.
            amount (int): quantity to send.

        Returns:
            tuple:
                InvocationTransaction: the transaction.
                int: the transaction fee.
                list: the neo VM evaluation stack results.
        """
        invoke_args = [self.ScriptHash.ToString(), 'transferFrom',
                       [parse_param(from_addr, wallet), parse_param(to_addr, wallet), parse_param(amount)]]

        tx, fee, results, num_ops = TestInvokeContract(wallet, invoke_args, None, True)

        return tx, fee, results
Пример #32
0
def lookup_contract_holds(wallet, contract_hash):

    invoke_args = [contract_hash.ToString(), parse_param('getAllHolds'), []]

    tx, fee, results, num_ops = TestInvokeContract(wallet, invoke_args, None,
                                                   False)

    if tx is not None and len(results) > 0:

        vins = parse_hold_vins(results)

        return vins

    raise Exception("Could not lookup contract holds")
Пример #33
0
    def test_ICOTemplate_4_locked_until(self):

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

        tx, results, total_ops, engine = TestBuild(out, [
            'get_locked_until',
            parse_param([bytearray(ECOSYSTEM_RESERVE_ADDRESS)])
        ], self.GetWallet1(), '0705', '05')
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].GetBigInteger(),
                         self.now_in_test + 3 * 30 * 86400)

        # cannot transfer to locked account
        test_transfer_amount = 2400000001
        tx, results, total_ops, engine = TestBuild(out, [
            'transfer',
            parse_param([
                bytearray(TOKEN_OWNER),
                bytearray(ECOSYSTEM_RESERVE_ADDRESS), test_transfer_amount
            ])
        ], self.GetWallet1(), '0705', '05')
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].GetBoolean(), False)

        # cannot transfer from locked account
        tx, results, total_ops, engine = TestBuild(
            out, [
                'transfer',
                parse_param([
                    bytearray(ECOSYSTEM_RESERVE_ADDRESS),
                    bytearray(TOKEN_OWNER), test_transfer_amount
                ])
            ], self.wallet['ECOSYSTEM_RESERVE_ADDRESS'], '0705', '05')
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].GetBoolean(), False)
Пример #34
0
def GatherLoadedContractParams(args, script):
    if len(args) < 4:
        raise Exception("please specify contract properties like {params} {return_type} {needs_storage} {needs_dynamic_invoke}")
    params = parse_param(args[0], ignore_int=True, prefer_hex=False)

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

    return_type = bytearray(binascii.unhexlify(str(args[1]).encode('utf-8')))

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

    contract_properties = 0

    if needs_storage:
        contract_properties += ContractPropertyState.HasStorage

    if needs_dynamic_invoke:
        contract_properties += ContractPropertyState.HasDynamicInvoke

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

    return out
Пример #35
0
    def Transfer(self, wallet, from_addr, to_addr, amount):
        """
        Transfer a specified amount of the NEP5Token to another address.

        Args:
            wallet (neo.Wallets.Wallet): a wallet instance.
            from_addr (str): public address of the account to transfer the given amount from.
            to_addr (str): public address of the account to transfer the given amount to.
            amount (int): quantity to send.

        Returns:
            tuple:
                InvocationTransaction: the transaction.
                int: the transaction fee.
                list: the neo VM evaluationstack results.
        """
        sb = ScriptBuilder()
        sb.EmitAppCallWithOperationAndArgs(self.ScriptHash, 'transfer',
                                           [parse_param(from_addr, wallet), parse_param(to_addr, wallet),
                                            parse_param(amount)])

        tx, fee, results, num_ops = test_invoke(sb.ToArray(), wallet, [], from_addr=from_addr)

        return tx, fee, results
Пример #36
0
def TestInvokeContract(wallet, args):

    BC = GetBlockchain()

    contract = BC.GetContract(args[0])

    if contract:
        descripe_contract(contract)

        verbose = False

        if 'verbose' in args:
            verbose = True
            args.remove('verbose')


#
        params = args[1:] if len(args) > 1 else []

        if len(params) > 0 and params[0] == 'describe':
            return

        params.reverse()

        sb = ScriptBuilder()

        for p in params:

            item = parse_param(p)
            sb.push(item)

        sb.EmitAppCall(contract.Code.ScriptHash().Data)

        out = sb.ToArray()

        return test_invoke(out, wallet)

    else:

        print("Contract %s not found" % args[0])

    return None, None
Пример #37
0
    def CrowdsaleRegister(self, wallet, register_addresses, from_addr=None):
        """
        Register for a crowd sale.

        Args:
            wallet (neo.Wallets.Wallet): a wallet instance.
            register_addresses (str): public address of the account that wants to register for the sale.

        Returns:
            tuple:
                InvocationTransaction: the transaction.
                int: the transaction fee.
                list: the neo VM evaluation stack results.
        """
        invoke_args = [self.ScriptHash.ToString(), 'crowdsale_register',
                       [parse_param(p, wallet) for p in register_addresses]]

        tx, fee, results, num_ops = TestInvokeContract(wallet, invoke_args, None, True, from_addr)

        return tx, fee, results
Пример #38
0
    def test_8_named_addr(self):

        wallet = self.GetWallet1()

        AddAlias(wallet, self.wallet_1_addr, 'my_named_addr')

        named = [n.Title for n in wallet.NamedAddr]

        self.assertIn('my_named_addr', named)

        param = 'my_named_addr'

        addr = lookup_addr_str(wallet, param)

        self.assertIsInstance(addr, UInt160)

        self.assertEqual(addr, self.wallet_1_script_hash)

        presult = parse_param(param, wallet)

        self.assertIsInstance(presult, bytearray)

        self.assertEqual(presult, self.wallet_1_script_hash.Data)
Пример #39
0
def TestInvokeContract(wallet, args, withdrawal_tx=None, parse_params=True, from_addr=None, min_fee=DEFAULT_MIN_FEE):

    BC = GetBlockchain()

    contract = BC.GetContract(args[0])

    if contract:

        verbose = False

        if 'verbose' in args:
            descripe_contract(contract)
            verbose = True
            args.remove('verbose')

#
        params = args[1:] if len(args) > 1 else []

        if len(params) > 0 and params[0] == 'describe':
            return

        params, neo_to_attach, gas_to_attach = get_asset_attachments(params)

        params.reverse()

        sb = ScriptBuilder()

        for p in params:

            if parse_params:
                item = parse_param(p, wallet)
            else:
                item = p

            if type(item) is list:
                item.reverse()
                listlength = len(item)
                for listitem in item:
                    sb.push(listitem)
                sb.push(listlength)
                sb.Emit(PACK)
            else:
                sb.push(item)

        sb.EmitAppCall(contract.Code.ScriptHash().Data)

        out = sb.ToArray()

        outputs = []

        if neo_to_attach:

            output = TransactionOutput(AssetId=Blockchain.SystemShare().Hash,
                                       Value=neo_to_attach,
                                       script_hash=contract.Code.ScriptHash(),
                                       )
            outputs.append(output)

        if gas_to_attach:

            output = TransactionOutput(AssetId=Blockchain.SystemCoin().Hash,
                                       Value=gas_to_attach,
                                       script_hash=contract.Code.ScriptHash())

            outputs.append(output)

        return test_invoke(out, wallet, outputs, withdrawal_tx, from_addr, min_fee)

    else:

        print("Contract %s not found" % args[0])

    return None, None, None, None
Пример #40
0
def test_deploy_and_invoke(deploy_script, invoke_args, wallet, from_addr=None, min_fee=DEFAULT_MIN_FEE, invocation_test_mode=True, debug_map=None):

    bc = GetBlockchain()

    sn = bc._db.snapshot()

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

    if settings.USE_DEBUG_STORAGE:
        debug_storage = DebugStorage.instance()
        debug_sn = debug_storage.db.snapshot()
        storages = DBCollection(debug_storage.db, debug_sn, DBPrefix.ST_Storage, StorageItem)
        storages.DebugStorage = True

    dtx = InvocationTransaction()
    dtx.Version = 1
    dtx.outputs = []
    dtx.inputs = []
    dtx.scripts = []
    dtx.Script = binascii.unhexlify(deploy_script)

    if from_addr is not None:
        from_addr = lookup_addr_str(wallet, from_addr)

    dtx = wallet.MakeTransaction(tx=dtx, from_addr=from_addr)
    context = ContractParametersContext(dtx)
    wallet.Sign(context)
    dtx.scripts = context.GetScripts()

    script_table = CachedScriptTable(contracts)
    service = StateMachine(accounts, validators, assets, contracts, storages, None)

    contract = wallet.GetDefaultContract()
    dtx.Attributes = [TransactionAttribute(usage=TransactionAttributeUsage.Script, data=Crypto.ToScriptHash(contract.Script, unhex=False))]

    to_dispatch = []

    engine = ApplicationEngine(
        trigger_type=TriggerType.Application,
        container=dtx,
        table=script_table,
        service=service,
        gas=dtx.Gas,
        testMode=True
    )

    engine.LoadScript(dtx.Script, False)

    # first we will execute the test deploy
    # then right after, we execute the test invoke

    d_success = engine.Execute()

    if d_success:

        items = engine.EvaluationStack.Items

        contract_state = None
        for i in items:
            if type(i) is ContractState:
                contract_state = i
                break
            elif type(i) is InteropInterface:
                item = i.GetInterface()
                if type(item) is ContractState:
                    contract_state = item
                    break

        shash = contract_state.Code.ScriptHash()

        invoke_args, neo_to_attach, gas_to_attach = get_asset_attachments(invoke_args)
        invoke_args.reverse()

        sb = ScriptBuilder()

        for p in invoke_args:

            item = parse_param(p, wallet)
            if type(item) is list:
                item.reverse()
                listlength = len(item)
                for listitem in item:
                    subitem = parse_param(listitem, wallet)
                    sb.push(subitem)
                sb.push(listlength)
                sb.Emit(PACK)
            else:
                sb.push(item)

        sb.EmitAppCall(shash.Data)
        out = sb.ToArray()

        outputs = []

        if neo_to_attach:
            output = TransactionOutput(AssetId=Blockchain.SystemShare().Hash,
                                       Value=neo_to_attach,
                                       script_hash=contract_state.Code.ScriptHash(),
                                       )
            outputs.append(output)

        if gas_to_attach:
            output = TransactionOutput(AssetId=Blockchain.SystemCoin().Hash,
                                       Value=gas_to_attach,
                                       script_hash=contract_state.Code.ScriptHash())

            outputs.append(output)

        itx = InvocationTransaction()
        itx.Version = 1
        itx.outputs = outputs
        itx.inputs = []
        itx.scripts = []
        itx.Attributes = []
        itx.Script = binascii.unhexlify(out)

        if len(outputs) < 1:
            contract = wallet.GetDefaultContract()
            itx.Attributes = [TransactionAttribute(usage=TransactionAttributeUsage.Script,
                                                   data=Crypto.ToScriptHash(contract.Script, unhex=False).Data)]

        itx = wallet.MakeTransaction(tx=itx, from_addr=from_addr)
        context = ContractParametersContext(itx)
        wallet.Sign(context)
        itx.scripts = context.GetScripts()

#            print("tx: %s " % json.dumps(itx.ToJson(), indent=4))

        engine = ApplicationEngine(
            trigger_type=TriggerType.Application,
            container=itx,
            table=script_table,
            service=service,
            gas=itx.Gas,
            testMode=invocation_test_mode
        )

        engine.LoadScript(itx.Script, False)
        engine.LoadDebugInfoForScriptHash(debug_map, shash.Data)

        # call execute in its own blocking thread

#        reactor.stop()

        i_success = engine.Execute()

        service.ExecutionCompleted(engine, i_success)
        to_dispatch = to_dispatch + service.events_to_dispatch

        for event in to_dispatch:
            events.emit(event.event_type, event)

        if i_success:
            service.TestCommit()
            if len(service.notifications) > 0:

                for n in service.notifications:
                    #                        print("NOTIFICATION : %s " % n)
                    Blockchain.Default().OnNotify(n)

            logger.info("Used %s Gas " % engine.GasConsumed().ToString())

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

            if consumed <= Fixed8.Zero():
                consumed = min_fee

            total_ops = engine.ops_processed

            # set the amount of gas the tx will need
            itx.Gas = consumed
            itx.Attributes = []
            result = engine.EvaluationStack.Items
            return itx, result, total_ops, engine
        else:
            print("error executing invoke contract...")

    else:
        print("error executing deploy contract.....")

    service.ExecutionCompleted(engine, False, 'error')

    return None, [], 0, None
Пример #41
0
def RequestWithdrawFrom(wallet, asset_id, contract_hash, to_addr, amount, require_password=True):
    asset_type = asset_id.lower()
    if asset_type not in ['neo', 'gas']:
        raise Exception('please specify neo or gas to withdraw')

    readable_addr = to_addr
    asset_id = get_asset_id(wallet, asset_type)

    contract = Blockchain.Default().GetContract(contract_hash)

    shash = contract.Code.ScriptHash()

    contract_addr = Crypto.ToAddress(shash)

    to_addr = parse_param(to_addr, wallet)
    amount = get_asset_amount(amount, asset_id)

    if shash not in wallet._watch_only:
        print("Add withdrawal contract address to your watch only: import watch_addr %s " % contract_addr)
        return False
    if amount < Fixed8.Zero():
        print("Cannot withdraw negative amount")
        return False

    unspents = wallet.FindUnspentCoinsByAssetAndTotal(
        asset_id=asset_id, amount=amount, from_addr=shash, use_standard=False, watch_only_val=64, reverse=True
    )

    if not unspents or len(unspents) == 0:
        print("no eligible withdrawal vins")
        return False

    balance = GetWithdrawalBalance(wallet, shash, to_addr, asset_type)

    balance_fixed8 = Fixed8(balance)
    orig_amount = amount
    if amount <= balance_fixed8:
        sb = ScriptBuilder()

        for uns in unspents:
            if amount > Fixed8.Zero():
                to_spend = amount
                if to_spend > uns.Output.Value:
                    to_spend = uns.Output.Value
                amount_bytes = bytearray(to_spend.value.to_bytes(8, 'little'))
                data = to_addr + amount_bytes
                data = data + uns.RefToBytes()
                sb.EmitAppCallWithOperationAndData(shash, 'withdraw_%s' % asset_type, data)
                amount -= uns.Output.Value

        tx, fee, results, num_ops = test_invoke(sb.ToArray(), wallet, [])

        for item in results:
            if not item.GetBoolean():
                print("Error performitng withdrawals")
                return False

        if require_password:
            print("\n---------------------------------------------------------------")
            print("Will make withdrawal request for %s %s from %s to %s " % (orig_amount.ToString(), asset_type, contract_addr, readable_addr))
            print("FEE IS %s " % fee.ToString())
            print("GAS IS %s " % tx.Gas.ToString())
            print("------------------------------------------------------------------\n")

            print("Enter your password to complete this request")

            passwd = prompt("[Password]> ", is_password=True)

            if not wallet.ValidatePassword(passwd):
                print("incorrect password")
                return

        result = InvokeContract(wallet, tx, fee)
        return result
    else:
        print("insufficient balance")
        return False