コード例 #1
0
ファイル: JsonRpcApi.py プロジェクト: kartava/neo-python
 def parse_send_many_params(self, params):
     if type(params[0]) is not list:
         raise JsonRpcError(-32602, "Invalid params")
     if len(params) not in [1, 2, 3]:
         raise JsonRpcError(-32602, "Invalid params")
     output = []
     for info in params[0]:
         asset = get_asset_id(self.wallet, info['asset'])
         if not type(asset) is UInt256:
             raise JsonRpcError(-32602, "Invalid params")
         address = info["address"]
         try:
             address = self.wallet.ToScriptHash(address)
         except Exception:
             raise JsonRpcError(-32602, "Invalid params")
         amount = Fixed8.TryParse(info["value"], require_positive=True)
         if not amount or float(info["value"]) == 0:
             raise JsonRpcError(-32602, "Invalid params")
         tx_output = TransactionOutput(AssetId=asset,
                                       Value=amount,
                                       script_hash=address)
         output.append(tx_output)
     contract_tx = ContractTransaction(outputs=output)
     fee = Fixed8.TryParse(params[1]) if len(params) >= 2 else Fixed8.Zero()
     if fee < Fixed8.Zero():
         raise JsonRpcError(-32602, "Invalid params")
     change_addr_sh = None
     if len(params) >= 3:
         change_addr = params[2]
         try:
             change_addr_sh = self.wallet.ToScriptHash(change_addr)
         except Exception:
             raise JsonRpcError(-32602, "Invalid params")
     return contract_tx, fee, change_addr_sh
コード例 #2
0
ファイル: JsonRpcApi.py プロジェクト: kartava/neo-python
 def parse_send_from_params(self, params):
     if len(params) not in [4, 5, 6]:
         raise JsonRpcError(-32602, "Invalid params")
     asset_id = get_asset_id(self.wallet, params[0])
     if not type(asset_id) is UInt256:
         raise JsonRpcError(-32602, "Invalid params")
     address_from = params[1]
     try:
         address_from_sh = self.wallet.ToScriptHash(address_from)
     except Exception:
         raise JsonRpcError(-32602, "Invalid params")
     address_to = params[2]
     try:
         address_to_sh = self.wallet.ToScriptHash(address_to)
     except Exception:
         raise JsonRpcError(-32602, "Invalid params")
     amount = Fixed8.TryParse(params[3], require_positive=True)
     if not amount or float(params[3]) == 0:
         raise JsonRpcError(-32602, "Invalid params")
     output = TransactionOutput(AssetId=asset_id,
                                Value=amount,
                                script_hash=address_to_sh)
     contract_tx = ContractTransaction(outputs=[output])
     fee = Fixed8.TryParse(params[4]) if len(params) >= 5 else Fixed8.Zero()
     if fee < Fixed8.Zero():
         raise JsonRpcError(-32602, "Invalid params")
     change_addr_sh = None
     if len(params) >= 6:
         change_addr = params[5]
         try:
             change_addr_sh = self.wallet.ToScriptHash(change_addr)
         except Exception:
             raise JsonRpcError(-32602, "Invalid params")
     return contract_tx, address_from_sh, fee, change_addr_sh
コード例 #3
0
ファイル: test_numbers.py プロジェクト: kartava/neo-python
    def test_various_methods(self):
        self.assertEqual(Fixed8.FD(), Fixed8(100000000))
        self.assertEqual(Fixed8.FD(), Fixed8.One())

        sat = Fixed8.Satoshi()
        self.assertEqual(sat, Fixed8(1))
        self.assertEqual(sat.value, 1)

        negsat = Fixed8.NegativeSatoshi()
        self.assertEqual(negsat, Fixed8(-1))
        self.assertEqual(negsat.value, -1)

        zero = Fixed8.Zero()
        self.assertEqual(zero, Fixed8(0))
        self.assertEqual(zero.value, 0)

        decimal = 1.2
        f8 = Fixed8.FromDecimal(decimal)
        self.assertEqual(f8.value, f8.GetData())

        f8 = Fixed8.TryParse(123.123)
        f8 = Fixed8.TryParse(123)

        self.assertEqual(f8.Size(), 8)

        zero = Fixed8.TryParse(0)
        self.assertEqual(zero, Fixed8(0))

        self.assertEqual(Fixed8.TryParse("foo"), None)
        self.assertEqual(Fixed8.TryParse(-1, require_positive=True), None)
コード例 #4
0
ファイル: Transaction.py プロジェクト: volekerb/neo-python
    def GetTransactionResults(self):
        """
        Get the execution results of the transaction.

        Returns:
            None: if the transaction has no references.
            list: of TransactionResult objects.
        """
        if self.References is None:
            return None

        results = []
        realresults = []
        for ref_output in self.References.values():
            results.append(
                TransactionResult(ref_output.AssetId, ref_output.Value))

        for output in self.outputs:
            results.append(
                TransactionResult(output.AssetId, output.Value * Fixed8(-1)))

        for key, group in groupby(results, lambda x: x.AssetId):
            sum = Fixed8(0)
            for item in group:
                sum = sum + item.Amount

            if sum != Fixed8.Zero():
                realresults.append(TransactionResult(key, sum))

        return realresults
コード例 #5
0
    def Run(snapshot,
            script,
            container=None,
            exit_on_error=False,
            gas=Fixed8.Zero(),
            test_mode=True,
            wb=None):
        """
        Runs a script in a test invoke environment

        Args:
            script (bytes): The script to run
            container (neo.Core.TX.Transaction): [optional] the transaction to use as the script container

        Returns:
            ApplicationEngine
        """

        engine = ApplicationEngine(TriggerType.Application, container,
                                   snapshot, gas, test_mode)

        # maybe not the best solution
        # but one for now
        if not wb:
            _script = binascii.unhexlify(script)
        else:
            _script = script

        engine.LoadScript(_script)
        engine.Execute()

        for event in engine._Service.events_to_dispatch:
            events.emit(event.event_type, event)

        return engine
コード例 #6
0
ファイル: Tokens.py プロジェクト: volekerb/neo-python
def do_token_transfer(token,
                      wallet,
                      from_address,
                      to_address,
                      amount,
                      fee=Fixed8.Zero(),
                      tx_attributes=None):
    if not tx_attributes:
        tx_attributes = []

    p_fee = fee

    # because we cannot differentiate between a normal and multisig from_addr, and because we want to make
    # sending NEP5 tokens straight forward even when sending from multisig addresses, we include the script_hash
    # for verification by default to the transaction attributes. See PR/Issue: https://github.com/CityOfZion/neo-python/pull/491
    from_script_hash = binascii.unhexlify(
        bytes(wallet.ToScriptHash(from_address).ToString2(), 'utf-8'))
    tx_attributes.append(
        TransactionAttribute(usage=TransactionAttributeUsage.Script,
                             data=from_script_hash))

    tx, fee, results = token.Transfer(wallet,
                                      from_address,
                                      to_address,
                                      amount,
                                      tx_attributes=tx_attributes)

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

        if results[0].GetBigInteger() == 1:
            print(
                "\n-----------------------------------------------------------"
            )
            print("Will transfer %s %s from %s to %s" % (string_from_amount(
                token, amount), token.symbol, from_address, to_address))
            print("Transfer fee: %s " % (fee.value / Fixed8.D))
            print(
                "-------------------------------------------------------------\n"
            )
            comb_fee = p_fee + fee
            if comb_fee != fee:
                print(
                    f"Priority Fee ({p_fee.value / Fixed8.D}) + Transfer Fee ({fee.value / Fixed8.D}) = {comb_fee.value / Fixed8.D}\n"
                )
            print("Enter your password to send to the network")

            try:
                passwd = prompt("[Password]> ", is_password=True)
            except KeyboardInterrupt:
                print("Transfer cancelled")
                return False
            if not wallet.ValidatePassword(passwd):
                print("incorrect password")
                return False

            return InvokeContract(wallet, tx, comb_fee)

    print("could not transfer tokens")
    return False
コード例 #7
0
def InvokeWithTokenVerificationScript(wallet, tx, token, fee=Fixed8.Zero(), invoke_attrs=None):
    try:
        wallet_tx = wallet.MakeTransaction(tx=tx, fee=fee, use_standard=True)
    except ValueError:
        print("Insufficient funds")
        return False

    if wallet_tx:

        token_contract_state = Blockchain.Default().GetContract(token.ScriptHash.ToString())
        print("token contract  %s " % token_contract_state)

        tx.Attributes = [
            TransactionAttribute(usage=TransactionAttributeUsage.Script,
                                 data=token.ScriptHash.Data)
        ]

        if invoke_attrs:
            tx.Attributes += invoke_attrs

        reedeem_script = token_contract_state.Code.Script.hex()

        # there has to be at least 1 param, and the first
        # one needs to be a signature param
        param_list = bytearray(b'\x00\x00')

        verification_contract = Contract.Create(reedeem_script, param_list, wallet.GetDefaultContract().PublicKeyHash)

        context = ContractParametersContext(wallet_tx)

        wallet.Sign(context)

        context.Add(verification_contract, 0, 0)

        if context.Completed:

            wallet_tx.scripts = context.GetScripts()

            nodemgr = NodeManager()
            relayed = nodemgr.relay(wallet_tx)

            if relayed:
                print("Relayed Tx: %s " % wallet_tx.Hash.ToString())

                # if it was relayed, we save tx
                wallet.SaveTransaction(wallet_tx)

                return wallet_tx
            else:
                print("Could not relay tx %s " % wallet_tx.Hash.ToString())
        else:

            print("Incomplete signature")

    else:
        print("Insufficient funds")

    return False
コード例 #8
0
def InvokeContract(wallet, tx, fee=Fixed8.Zero(), from_addr=None, owners=None):
    if from_addr is not None:
        from_addr = PromptUtils.lookup_addr_str(wallet, from_addr)

    try:
        wallet_tx = wallet.MakeTransaction(tx=tx,
                                           fee=fee,
                                           use_standard=True,
                                           from_addr=from_addr)
    except ValueError:
        print("Insufficient funds")
        return False
    except TXFeeError as e:
        print(e)
        return False

    if wallet_tx:

        if owners:
            for owner in list(owners):
                wallet_tx.Attributes.append(
                    TransactionAttribute(
                        usage=TransactionAttributeUsage.Script, data=owner))
            wallet_tx.Attributes = make_unique_script_attr(tx.Attributes)

        context = ContractParametersContext(wallet_tx)
        wallet.Sign(context)

        if owners:
            gather_signatures(context, wallet_tx, list(owners))

        if context.Completed:

            wallet_tx.scripts = context.GetScripts()

            relayed = False

            #            print("SENDING TX: %s " % json.dumps(wallet_tx.ToJson(), indent=4))

            relayed = NodeLeader.Instance().Relay(wallet_tx)

            if relayed:
                print("Relayed Tx: %s " % wallet_tx.Hash.ToString())

                wallet.SaveTransaction(wallet_tx)

                return wallet_tx
            else:
                print("Could not relay tx %s " % wallet_tx.Hash.ToString())
        else:

            print("Incomplete signature")

    else:
        print("Insufficient funds")

    return False
コード例 #9
0
ファイル: StateDescriptor.py プロジェクト: kartava/neo-python
    def GetSystemFee_Validator(self):

        if self.Field == "Registered":
            for character in self.Value:
                if character != '0':
                    return Fixed8.FromDecimal(1000)
            return Fixed8.Zero()

        raise Exception("Invalid operation")
コード例 #10
0
    def execute(self, arguments):
        wallet = PromptData.Wallet

        if len(arguments) < 4:
            print("Please specify the required parameters")
            return

        if len(arguments) > 5:
            # the 5th argument is the optional attributes,
            print("Too many parameters supplied. Please check your command")
            return

        addr = arguments[0]
        if not isValidPublicAddress(addr):
            print("Invalid address specified")
            return

        try:
            from_addr = wallet.ToScriptHash(addr)
        except ValueError as e:
            print(str(e))
            return

        asset_id = PromptUtils.get_asset_id(wallet, arguments[1])
        if not asset_id:
            print(f"Unknown asset id: {arguments[1]}")
            return

        try:
            index = int(arguments[2])
        except ValueError:
            print(f"Invalid unspent index value: {arguments[2]}")
            return

        try:
            divisions = int(arguments[3])
        except ValueError:
            print(f"Invalid divisions value: {arguments[3]}")
            return

        if divisions < 2:
            print("Divisions cannot be lower than 2")
            return

        if len(arguments) == 5:
            fee = Fixed8.TryParse(arguments[4], require_positive=True)
            if not fee:
                print(f"Invalid fee value: {arguments[4]}")
                return
        else:
            fee = Fixed8.Zero()

        return SplitUnspentCoin(wallet, asset_id, from_addr, index, divisions,
                                fee)
コード例 #11
0
    def SystemFee(self):
        """
        Get the system fee.

        Returns:
            Fixed8:
        """
        if self.Version >= 1:
            return Fixed8.Zero()

        # if all outputs are NEO or gas, return 0
        all_neo_gas = True
        for output in self.outputs:
            if output.AssetId != GetSystemCoin(
            ).Hash and output.AssetId != GetSystemShare().Hash:
                all_neo_gas = False
        if all_neo_gas:
            return Fixed8.Zero()

        return super(IssueTransaction, self).SystemFee()
コード例 #12
0
    def TotalFees(self):
        """
        Get the total transaction fees in the block.

        Returns:
            Fixed8:
        """
        amount = Fixed8.Zero()
        for tx in self.Transactions:
            amount += tx.SystemFee()
        return amount
コード例 #13
0
    def SystemFee(self):
        """
        Get the system fee.

        Returns:
            Fixed8:
        """
        if self.AssetType == AssetType.GoverningToken or self.AssetType == AssetType.UtilityToken:
            return Fixed8.Zero()

        return super(RegisterTransaction, self).SystemFee()
コード例 #14
0
    def CalcChange(self, change_addr=None):
        """
        Calculates the change output(s). NOTE: Assumes all other outputs have been added.

        Args:
            change_addr: (str, optional) specify a change address. NOTE: Defaults to the sourceAddress.
        """
        if not change_addr:
            change_addr = self.SOURCE_SCRIPTHASH
        if change_addr != self.SOURCE_SCRIPTHASH:
            change_hash = Helper.AddrStrToScriptHash(
                change_addr)  # also verifies if the address is valid
        else:
            change_hash = change_addr

        if not self.outputs:
            raise RawTXError(
                "Please specify outputs prior to creating change output(s).")

        neo = []
        gas = []
        for output in self.outputs:
            if output.AssetId == UInt256.ParseString(self.neo_asset_id):
                neo.append(output.Value.value)
            elif output.AssetId == UInt256.ParseString(self.gas_asset_id):
                gas.append(output.Value.value)
        if self.SystemFee() > Fixed8.Zero():
            gas.append(self.SystemFee().value)
        if self._network_fee:
            if self._network_fee > Fixed8.Zero():
                gas.append(self._network_fee.value)
        neo_total = 0
        gas_total = 0
        for asset in self.BALANCE:
            if asset['asset_hash'] == self.neo_asset_id:
                neo_total = asset['amount']
            elif asset['asset_hash'] == self.gas_asset_id:
                gas_total = asset['amount']
        neo_diff = Fixed8.FromDecimal(neo_total) - Fixed8(sum(neo))
        gas_diff = Fixed8.FromDecimal(gas_total) - Fixed8(sum(gas))

        if neo_diff < Fixed8.Zero() or gas_diff < Fixed8.Zero():
            raise AssetError('Total outputs exceed the available unspents.')

        if neo_diff > Fixed8.Zero():
            self.outputs.append(
                TransactionOutput(AssetId=UInt256.ParseString(
                    self.neo_asset_id),
                                  Value=neo_diff,
                                  script_hash=change_hash))
        if gas_diff > Fixed8.Zero() and Fixed8(sum(gas)) > Fixed8.Zero():
            self.outputs.append(
                TransactionOutput(AssetId=UInt256.ParseString(
                    self.gas_asset_id),
                                  Value=gas_diff,
                                  script_hash=change_hash))
コード例 #15
0
ファイル: WalletAddress.py プロジェクト: kartava/neo-python
def split_to_vouts(asset, addr, input_val, divisions):
    divisor = Fixed8(divisions)

    new_amounts = input_val / divisor
    outputs = []
    total = Fixed8.Zero()

    if asset == Blockchain.Default().SystemShare().Hash:
        if new_amounts % Fixed8.FD() > Fixed8.Zero():
            new_amounts = new_amounts.Ceil()

    while total < input_val:
        if total + new_amounts < input_val:
            outputs.append(TransactionOutput(asset, new_amounts, addr))
            total += new_amounts
        else:
            diff = input_val - total
            outputs.append(TransactionOutput(asset, diff, addr))
            total += diff

    return outputs
コード例 #16
0
    def Run(script, container=None, exit_on_error=False, gas=Fixed8.Zero(), test_mode=True):
        """
        Runs a script in a test invoke environment

        Args:
            script (bytes): The script to run
            container (neo.Core.TX.Transaction): [optional] the transaction to use as the script container

        Returns:
            ApplicationEngine
        """

        from neo.Core.Blockchain import Blockchain
        from neo.SmartContract.StateMachine import StateMachine
        from neo.EventHub import events

        bc = Blockchain.Default()

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

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

        engine = ApplicationEngine(
            trigger_type=TriggerType.Application,
            container=container,
            table=script_table,
            service=service,
            gas=gas,
            testMode=test_mode,
            exit_on_error=exit_on_error
        )

        script = binascii.unhexlify(script)

        engine.LoadScript(script)

        try:
            success = engine.Execute()
            engine.testMode = True
            service.ExecutionCompleted(engine, success)
        except Exception as e:
            engine.testMode = True
            service.ExecutionCompleted(engine, False, e)

        for event in service.events_to_dispatch:
            events.emit(event.event_type, event)

        return engine
コード例 #17
0
def InvokeContract(wallet, tx, fee=Fixed8.Zero(), from_addr=None, owners=None):
    if from_addr is not None:
        from_addr = PromptUtils.lookup_addr_str(wallet, from_addr)

    try:
        wallet_tx = wallet.MakeTransaction(tx=tx, fee=fee, use_standard=True, from_addr=from_addr)
    except ValueError:
        print("Insufficient funds")
        return False

    if wallet_tx:

        if owners:
            for owner in list(owners):
                wallet_tx.Attributes.append(TransactionAttribute(usage=TransactionAttributeUsage.Script, data=owner))
            wallet_tx.Attributes = make_unique_script_attr(tx.Attributes)

        context = ContractParametersContext(wallet_tx)
        wallet.Sign(context)

        if owners:
            gather_signatures(context, wallet_tx, list(owners))

        if context.Completed:

            wallet_tx.scripts = context.GetScripts()

            passed, reason = validate_simple_policy(wallet_tx)
            if not passed:
                print(reason)
                return False

            nodemgr = NodeManager()
            relayed = nodemgr.relay(wallet_tx)

            if relayed:
                print("Relayed Tx: %s " % wallet_tx.Hash.ToString())

                wallet.SaveTransaction(wallet_tx)

                return wallet_tx
            else:
                print("Could not relay tx %s " % wallet_tx.Hash.ToString())
        else:

            print("Incomplete signature")

    else:
        print("Insufficient funds")

    return False
コード例 #18
0
ファイル: Tokens.py プロジェクト: volekerb/neo-python
def token_mint(token,
               wallet,
               to_addr,
               asset_attachments=[],
               fee=Fixed8.Zero(),
               invoke_attrs=None):
    if not invoke_attrs:
        invoke_attrs = []

    p_fee = fee

    tx, fee, results = token.Mint(wallet,
                                  to_addr,
                                  asset_attachments,
                                  invoke_attrs=invoke_attrs)

    if tx is not None and results is not None:
        if len(results) > 0 and results[0] is not None:
            print(
                "\n-----------------------------------------------------------"
            )
            print(f"[{token.symbol}] Will mint tokens to address: {to_addr}")
            print(f"Invocation Fee: {fee.value / Fixed8.D}")
            print(
                "-------------------------------------------------------------\n"
            )
            comb_fee = p_fee + fee
            if comb_fee != fee:
                print(
                    f"Priority Fee ({p_fee.value / Fixed8.D}) + Invocation Fee ({fee.value / Fixed8.D}) = {comb_fee.value / Fixed8.D}\n"
                )
            print("Enter your password to send to the network")

            try:
                passwd = prompt("[Password]> ", is_password=True)
            except KeyboardInterrupt:
                print("Token mint cancelled")
                return False
            if not wallet.ValidatePassword(passwd):
                print("incorrect password")
                return False

            return InvokeWithTokenVerificationScript(wallet,
                                                     tx,
                                                     token,
                                                     comb_fee,
                                                     invoke_attrs=invoke_attrs)

    print("Failed to mint tokens")
    return False
コード例 #19
0
ファイル: Tokens.py プロジェクト: volekerb/neo-python
def token_send(wallet,
               token_str,
               from_addr,
               to_addr,
               amount,
               fee=Fixed8.Zero(),
               user_tx_attributes=None):
    """
    Send `amount` of tokens from `from_addr` to `to_addr`

    Args:
        wallet (Wallet): a UserWallet instance
        token_str (str): symbol name or script_hash
        from_addr (str): a wallet address
        to_addr (str): a wallet address
        amount (float): the number of tokens to send
        fee (Fixed8): (optional) a fee to give the transaction priority (> 0.001) 
        user_tx_attributes (list): a list of ``TransactionAttribute``s.

    Raises:
        ValueError: for invalid arguments

    Returns:
        a Transaction object if successful, False otherwise.
    """
    if not user_tx_attributes:
        user_tx_attributes = []

    try:
        token = _validate_nep5_args(wallet, token_str, from_addr, to_addr,
                                    amount)
    except ValueError:
        # just making it explicit for the reader
        raise

    for attr in user_tx_attributes:
        if not isinstance(attr, TransactionAttribute):
            raise ValueError(f"{attr} is not a valid transaction attribute")

    decimal_amount = amount_from_string(token, amount)

    return do_token_transfer(token,
                             wallet,
                             from_addr,
                             to_addr,
                             decimal_amount,
                             fee=fee,
                             tx_attributes=user_tx_attributes)
コード例 #20
0
    def __init__(self, pub_key=None):
        """
        Create an instance.

        Args:
            pub_key (EllipticCurve.ECPoint):

        Raises:
            Exception: if `pub_key` is not a valid ECPoint.
        """
        if pub_key is not None and type(pub_key) is not EllipticCurve.ECPoint:
            raise Exception("Pubkey must be ECPoint Instance")

        self.PublicKey = pub_key
        self.Registered = False
        self.Votes = Fixed8.Zero()
コード例 #21
0
ファイル: Blockchain.py プロジェクト: kartava/neo-python
    def CalculateBonusInternal(unclaimed):
        amount_claimed = Fixed8.Zero()

        decInterval = Blockchain.DECREMENT_INTERVAL
        genAmount = Blockchain.GENERATION_AMOUNT
        genLen = len(genAmount)

        for coinheight, group in groupby(unclaimed, lambda x: x.Heights):
            amount = 0
            ustart = int(coinheight.start / decInterval)

            if ustart < genLen:

                istart = coinheight.start % decInterval
                uend = int(coinheight.end / decInterval)
                iend = coinheight.end % decInterval

                if uend >= genLen:
                    iend = 0

                if iend == 0:
                    uend -= 1
                    iend = decInterval

                while ustart < uend:
                    amount += (decInterval - istart) * genAmount[ustart]
                    ustart += 1
                    istart = 0

                amount += (iend - istart) * genAmount[ustart]

            endamount = Blockchain.Default().GetSysFeeAmountByHeight(
                coinheight.end - 1)
            startamount = 0 if coinheight.start == 0 else Blockchain.Default(
            ).GetSysFeeAmountByHeight(coinheight.start - 1)
            amount += endamount - startamount

            outputSum = 0

            for spentcoin in group:
                outputSum += spentcoin.Value.value

            outputSum = outputSum / 100000000
            outputSumFixed8 = Fixed8(int(outputSum * amount))
            amount_claimed += outputSumFixed8

        return amount_claimed
コード例 #22
0
ファイル: Tokens.py プロジェクト: volekerb/neo-python
    def execute(self, arguments):
        wallet = PromptData.Wallet

        if len(arguments) < 4:
            print("Please specify the required parameters")
            return False

        if len(arguments) > 6:
            # the 5th and 6th arguments are optional
            print("Too many parameters supplied. Please check your command")
            return False

        arguments, priority_fee = PromptUtils.get_fee(arguments)
        arguments, user_tx_attributes = PromptUtils.get_tx_attr_from_args(
            arguments)

        token = arguments[0]
        from_addr = arguments[1]
        to_addr = arguments[2]
        try:
            amount = float(arguments[3])
        except ValueError:
            print(f"{arguments[3]} is not a valid amount")
            return False

        fee = Fixed8.Zero()
        if priority_fee is not None:
            fee = priority_fee
            if fee is False:
                logger.debug("invalid fee")
                return False

        try:
            success = token_send(wallet,
                                 token,
                                 from_addr,
                                 to_addr,
                                 amount,
                                 fee=fee,
                                 user_tx_attributes=user_tx_attributes)
        except ValueError as e:
            # occurs if arguments are invalid
            print(str(e))
            success = False

        return success
コード例 #23
0
    def test_1_no_available_claim(self):

        wallet = self.GetWallet3()

        unspents = wallet.FindUnspentCoinsByAsset(self.NEO)

        self.assertEqual(1, len(unspents))

        unavailable_bonus = wallet.GetUnavailableBonus()

        self.assertEqual(Fixed8.FromDecimal(0.0002685), unavailable_bonus)

        unclaimed_coins = wallet.GetUnclaimedCoins()

        self.assertEqual(0, len(unclaimed_coins))

        available_bonus = wallet.GetAvailableClaimTotal()

        self.assertEqual(Fixed8.Zero(), available_bonus)
コード例 #24
0
    def Validate(self):
        """
        Validate the transaction.
        """
        if self.Size() > self.MAX_TX_SIZE:
            raise TXAttributeError('Maximum transaction size exceeded.')

        # calculate and verify the required network fee for the tx
        if not self._network_fee:
            self._network_fee = Fixed8.Zero()
        fee = self._network_fee
        if self.Size() > settings.MAX_FREE_TX_SIZE:
            req_fee = Fixed8.FromDecimal(
                settings.FEE_PER_EXTRA_BYTE *
                (self.Size() - settings.MAX_FREE_TX_SIZE))
            if req_fee < settings.LOW_PRIORITY_THRESHOLD:
                req_fee = settings.LOW_PRIORITY_THRESHOLD
            if fee < req_fee:
                raise TXFeeError(
                    f'The tx size ({self.Size()}) exceeds the max free tx size ({settings.MAX_FREE_TX_SIZE}).\nA network fee of {req_fee.ToString()} GAS is required.'
                )
コード例 #25
0
    def DeserializeExclusiveData(self, reader):
        """
        Deserialize full object.

        Args:
            reader (neo.IO.BinaryReader):
        """
        if self.Type == b'\x02':  # ClaimTransaction
            if self.Version != 0:
                raise FormatError('Invalid format')

            numrefs = reader.ReadVarInt()

            claims = []
            for i in range(0, numrefs):
                c = CoinReference()
                c.Deserialize(reader)
                claims.append(c)

            self.Claims = claims
            if len(self.Claims) == 0:
                raise FormatError('Invalid format')

        elif self.Type == b'\xd1':  # InvocationTransaction
            if self.Version > 1:
                raise FormatError('Invalid format')

            self.Script = reader.ReadVarBytes()

            if len(self.Script) == 0:
                raise FormatError('Invalid Format')

            if self.Version >= 1:
                self.Gas = reader.ReadFixed8()
                if self.Gas < Fixed8.Zero():
                    raise FormatError("Invalid Format")
            else:
                self.Gas = Fixed8(0)
        else:
            super(RawTransaction, self).DeserializeExclusiveData(reader=reader)
コード例 #26
0
    def DeserializeExclusiveData(self, reader):
        """
        Deserialize full object.

        Args:
            reader (neo.IO.BinaryReader):

        Raises:
            Exception: If the version read is incorrect.
        """
        if self.Version > 1:
            raise Exception('Invalid format')

        self.Script = reader.ReadVarBytes()

        if len(self.Script) == 0:
            raise Exception('Invalid Format')

        if self.Version >= 1:
            self.Gas = reader.ReadFixed8()
            if self.Gas < Fixed8.Zero():
                raise Exception("Invalid Format")
        else:
            self.Gas = Fixed8(0)
コード例 #27
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,
                           invoke_attrs=None,
                           owners=None):
    bc = GetBlockchain()

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

    if settings.USE_DEBUG_STORAGE:
        debug_storage = DebugStorage.instance()
        storages = DBCollection(debug_storage.db, 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 = PromptUtils.lookup_addr_str(wallet, from_addr)

    try:
        dtx = wallet.MakeTransaction(tx=dtx, from_addr=from_addr)
    except (ValueError, TXFeeError):
        pass

    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))
    ]
    dtx.Attributes = make_unique_script_attr(dtx.Attributes)

    to_dispatch = []

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

    engine.LoadScript(dtx.Script)

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

    d_success = engine.Execute()

    if d_success:

        items = engine.ResultStack.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 = PromptUtils.get_asset_attachments(
            invoke_args)
        invoke_args, no_parse_addresses = PromptUtils.get_parse_addresses(
            invoke_args)

        invoke_args.reverse()

        if '--i' in invoke_args:
            invoke_args = []
            for index, iarg in enumerate(contract_state.Code.ParameterList):
                param, abort = PromptUtils.gather_param(index, iarg)
                if abort:
                    return None, [], 0, None
                else:
                    invoke_args.append(param)
            invoke_args.reverse()

        sb = ScriptBuilder()

        for p in invoke_args:
            item = PromptUtils.parse_param(p,
                                           wallet,
                                           parse_addr=no_parse_addresses)
            if type(item) is list:
                item.reverse()
                listlength = len(item)
                for listitem in item:
                    subitem = PromptUtils.parse_param(
                        listitem, wallet, parse_addr=no_parse_addresses)
                    if type(subitem) is list:
                        subitem.reverse()
                        for listitem2 in subitem:
                            subsub = PromptUtils.parse_param(
                                listitem2,
                                wallet,
                                parse_addr=no_parse_addresses)
                            sb.push(subsub)
                        sb.push(len(subitem))
                        sb.Emit(PACK)
                    else:
                        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 = deepcopy(invoke_attrs) if invoke_attrs else []
        itx.Script = binascii.unhexlify(out)

        if len(outputs) < 1 and not owners:
            contract = wallet.GetDefaultContract()
            itx.Attributes.append(
                TransactionAttribute(usage=TransactionAttributeUsage.Script,
                                     data=contract.ScriptHash))
            itx.Attributes = make_unique_script_attr(itx.Attributes)

        try:
            itx = wallet.MakeTransaction(tx=itx, from_addr=from_addr)
        except (ValueError, TXFeeError):
            pass

        context = ContractParametersContext(itx)
        wallet.Sign(context)

        if owners:
            owners = list(owners)
            for owner in owners:
                itx.Attributes.append(
                    TransactionAttribute(
                        usage=TransactionAttributeUsage.Script, data=owner))
                itx.Attributes = make_unique_script_attr(itx.Attributes)
            context = ContractParametersContext(itx, isMultiSig=True)

        if context.Completed:
            itx.scripts = context.GetScripts()
        else:
            logger.warn(
                "Not gathering signatures for test build.  For a non-test invoke that would occur here."
            )
        #            if not gather_signatures(context, itx, owners):
        #                return None, [], 0, None

        #        print("gathered signatures %s " % itx.scripts)

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

        engine.invocation_args = invoke_args
        engine.LoadScript(itx.Script)
        engine.LoadDebugInfoForScriptHash(debug_map, shash.Data)

        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:
                    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.ResultStack.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
コード例 #28
0
def test_invoke(script,
                wallet,
                outputs,
                withdrawal_tx=None,
                from_addr=None,
                min_fee=DEFAULT_MIN_FEE,
                invoke_attrs=None,
                owners=None):
    # print("invoke script %s " % script)

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

    bc = GetBlockchain()

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

    # if we are using a withdrawal tx, don't recreate the invocation tx
    # also, we don't want to reset the inputs / outputs
    # since those were already calculated
    if withdrawal_tx is not None:
        tx = withdrawal_tx

    else:
        tx = InvocationTransaction()
        tx.outputs = outputs
        tx.inputs = []

    tx.Version = 1
    tx.scripts = []
    tx.Script = binascii.unhexlify(script)
    tx.Attributes = [] if invoke_attrs is None else deepcopy(invoke_attrs)

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

    if len(outputs) < 1:
        contract = wallet.GetDefaultContract()
        tx.Attributes.append(
            TransactionAttribute(usage=TransactionAttributeUsage.Script,
                                 data=contract.ScriptHash))
        tx.Attributes = make_unique_script_attr(tx.Attributes)

    # same as above. we don't want to re-make the transaction if it is a withdrawal tx
    if withdrawal_tx is not None:
        wallet_tx = tx
    else:
        try:
            wallet_tx = wallet.MakeTransaction(tx=tx,
                                               from_addr=from_addr,
                                               skip_fee_calc=True)
        except ValueError:
            pass

    context = ContractParametersContext(wallet_tx)
    wallet.Sign(context)

    if owners:
        owners = list(owners)
        for owner in owners:
            #            print("contract %s %s" % (wallet.GetDefaultContract().ScriptHash, owner))
            if wallet.GetDefaultContract().ScriptHash != owner:
                wallet_tx.Attributes.append(
                    TransactionAttribute(
                        usage=TransactionAttributeUsage.Script, data=owner))
                wallet_tx.Attributes = make_unique_script_attr(tx.Attributes)
        context = ContractParametersContext(wallet_tx, isMultiSig=True)

    if context.Completed:
        wallet_tx.scripts = context.GetScripts()
    else:
        logger.warning(
            "Not gathering signatures for test build.  For a non-test invoke that would occur here."
        )
    #        if not gather_signatures(context, wallet_tx, owners):
    #            return None, [], 0, None

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

    engine.LoadScript(wallet_tx.Script)

    try:
        success = engine.Execute()

        service.ExecutionCompleted(engine, success)

        for event in service.events_to_dispatch:
            events.emit(event.event_type, event)

        if success:

            # this will be removed in favor of neo.EventHub
            if len(service.notifications) > 0:
                for n in service.notifications:
                    Blockchain.Default().OnNotify(n)

            # print("Used %s Gas " % engine.GasConsumed().ToString())

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

            net_fee = None
            tx_gas = None

            if consumed <= Fixed8.Zero():
                net_fee = min_fee
                tx_gas = Fixed8.Zero()
            else:
                tx_gas = consumed
                net_fee = Fixed8.Zero()

            # set the amount of gas the tx will need
            wallet_tx.Gas = tx_gas
            # reset the wallet outputs
            wallet_tx.outputs = outputs
            wallet_tx.Attributes = [] if invoke_attrs is None else deepcopy(
                invoke_attrs)

            # calculate the required network fee for the tx and compare to fee
            if wallet_tx.Size() > settings.MAX_FREE_TX_SIZE:
                req_fee = Fixed8.FromDecimal(
                    settings.FEE_PER_EXTRA_BYTE *
                    (wallet_tx.Size() - settings.MAX_FREE_TX_SIZE))
                if req_fee < settings.LOW_PRIORITY_THRESHOLD:
                    req_fee = settings.LOW_PRIORITY_THRESHOLD
                if net_fee < req_fee:
                    net_fee = req_fee

            return wallet_tx, net_fee, engine.ResultStack.Items, engine.ops_processed, success

        # this allows you to to test invocations that fail
        else:
            wallet_tx.outputs = outputs
            wallet_tx.Attributes = [] if invoke_attrs is None else deepcopy(
                invoke_attrs)
            return wallet_tx, min_fee, [], engine.ops_processed, success

    except Exception as e:
        service.ExecutionCompleted(engine, False, e)

    return None, None, None, None, False
コード例 #29
0
def construct_send_many(wallet, arguments):
    if len(arguments) is 0:
        print("Please specify the required parameter")
        return

    outgoing = get_arg(arguments, convert_to_int=True)
    if outgoing is None:
        print("Invalid outgoing number")
        return
    if outgoing < 1:
        print("Outgoing number must be >= 1")
        return

    arguments, from_address = get_from_addr(arguments)
    arguments, change_address = get_change_addr(arguments)
    arguments, priority_fee = get_fee(arguments)
    arguments, owners = get_owners_from_params(arguments)
    arguments, user_tx_attributes = get_tx_attr_from_args(arguments)

    output = []
    for i in range(outgoing):
        try:
            print('Outgoing Number ', i + 1)
            to_send = prompt("Asset to send: ")
            assetId = get_asset_id(wallet, to_send)
            if assetId is None:
                print("Asset id not found")
                return
            if type(assetId) is NEP5Token:
                print('sendmany does not support NEP5 tokens')
                return
            address_to = prompt("Address to: ")
            scripthash_to = lookup_addr_str(wallet, address_to)
            if scripthash_to is None:
                logger.debug("invalid destination address")
                return
            amount = prompt("Amount to send: ")
            f8amount = get_asset_amount(amount, assetId)
            if f8amount is False:
                logger.debug("invalid amount")
                return
            if float(amount) == 0:
                print("Amount cannot be 0")
                return
            tx_output = TransactionOutput(AssetId=assetId,
                                          Value=f8amount,
                                          script_hash=scripthash_to)
            output.append(tx_output)
        except KeyboardInterrupt:
            print('Transaction cancelled')
            return
    contract_tx = ContractTransaction(outputs=output)

    scripthash_from = None

    if from_address is not None:
        scripthash_from = lookup_addr_str(wallet, from_address)
        if scripthash_from is None:
            logger.debug("invalid source address")
            return

    scripthash_change = None

    if change_address is not None:
        scripthash_change = lookup_addr_str(wallet, change_address)
        if scripthash_change is None:
            logger.debug("invalid change address")
            return

    fee = Fixed8.Zero()
    if priority_fee is not None:
        fee = priority_fee
        if fee is False:
            logger.debug("invalid fee")
            return

    print(f"Sending with fee: {fee.ToString()}")
    return [
        contract_tx, scripthash_from, scripthash_change, fee, owners,
        user_tx_attributes
    ]
コード例 #30
0
def construct_send_basic(wallet, arguments):
    if len(arguments) < 3:
        print("Please specify the required parameters")
        return

    arguments, from_address = get_from_addr(arguments)
    arguments, priority_fee = get_fee(arguments)
    arguments, user_tx_attributes = get_tx_attr_from_args(arguments)
    arguments, owners = get_owners_from_params(arguments)
    to_send = get_arg(arguments)
    address_to = get_arg(arguments, 1)
    amount = get_arg(arguments, 2)

    assetId = get_asset_id(wallet, to_send)
    if assetId is None:
        print("Asset id not found")
        return

    scripthash_to = lookup_addr_str(wallet, address_to)
    if scripthash_to is None:
        logger.debug("invalid destination address")
        return

    scripthash_from = None
    if from_address is not None:
        scripthash_from = lookup_addr_str(wallet, from_address)
        if scripthash_from is None:
            logger.debug("invalid source address")
            return

    # if this is a token, we will use a different
    # transfer mechanism
    if type(assetId) is NEP5Token:
        return do_token_transfer(assetId,
                                 wallet,
                                 from_address,
                                 address_to,
                                 amount_from_string(assetId, amount),
                                 tx_attributes=user_tx_attributes)

    f8amount = get_asset_amount(amount, assetId)
    if f8amount is False:
        logger.debug("invalid amount")
        return
    if float(amount) == 0:
        print("Amount cannot be 0")
        return

    fee = Fixed8.Zero()
    if priority_fee is not None:
        fee = priority_fee
        if fee is False:
            logger.debug("invalid fee")
            return
    print(f"Sending with fee: {fee.ToString()}")

    output = TransactionOutput(AssetId=assetId,
                               Value=f8amount,
                               script_hash=scripthash_to)
    contract_tx = ContractTransaction(outputs=[output])
    return [contract_tx, scripthash_from, fee, owners, user_tx_attributes]