示例#1
0
    def Run(script, container=None):

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

        bc = Blockchain.Default()

        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)

        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=Fixed8.Zero(),
                                   testMode=True)

        engine.LoadScript(script, False)

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

        return engine
    def test_contract_create_block(self):

        hexdata = binascii.unhexlify(self.contract_create_block)

        block = Helper.AsSerializableWithType(hexdata, 'neo.Core.Block.Block')

        self.assertEqual(block.Index, self.contract_block_index)

        result = Blockchain.Default().Persist(block)

        self.assertTrue(result)

        snapshot = Blockchain.Default()._db.snapshot()

        contracts = DBCollection(Blockchain.Default()._db, snapshot,
                                 DBPrefix.ST_Contract, ContractState)

        contract_added = contracts.TryGet(self.contract_hash)

        self.assertIsNotNone(contract_added)

        self.assertEqual(contract_added.HasStorage, False)
        self.assertEqual(contract_added.Payable, False)
        self.assertEqual(contract_added.Name, b'test create')
        self.assertEqual(contract_added.Email, b'*****@*****.**')

        self.assertEqual(
            len(Blockchain.Default().SearchContracts("test create")), 1)
        self.assertEqual(
            len(Blockchain.Default().SearchContracts("TEST CREate")), 1)
        self.assertEqual(
            len(Blockchain.Default().SearchContracts("TEST CREATE!")), 0)

        code = contract_added.Code

        self.assertIsNotNone(code)

        self.assertEqual(code.ReturnType, 255)

        self.assertEqual(code.ScriptHash().ToBytes(), self.contract_hash)
        self.assertEqual(code.Script.hex().encode('utf-8'),
                         self.contract_block_script)

        snapshot.close()
示例#3
0
    def Runtime_Notify(self, engine):

        state = engine.EvaluationStack.Pop()

        payload = ContractParameter.ToParameter(state)

        args = NotifyEventArgs(
            engine.ScriptContainer,
            UInt160(data=engine.CurrentContext.ScriptHash()),
            payload
        )

        self.notifications.append(args)

        if settings.emit_notify_events_on_sc_execution_error:
            # emit Notify events even if the SC execution might fail.
            tx_hash = engine.ScriptContainer.Hash
            height = Blockchain.Default().Height + 1
            success = None
            self.events_to_dispatch.append(NotifyEvent(SmartContractEvent.RUNTIME_NOTIFY, payload,
                                                       args.ScriptHash, height, tx_hash,
                                                       success, engine.testMode))

        return True
示例#4
0
def ImportContractAddr(wallet, contract_hash, pubkey_script_hash):
    """
    Args:
        wallet (Wallet): a UserWallet instance
        contract_hash (UInt160): hash of the contract to import
        pubkey_script_hash (UInt160):

    Returns:
        neo.SmartContract.Contract.Contract
    """

    contract = Blockchain.Default().GetContract(contract_hash)
    if not contract or not pubkey_script_hash:
        print("Could not find contract")
        return

    reedeem_script = contract.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')

    # if there's more than one param
    # we set the first parameter to be the signature param
    if len(contract.Code.ParameterList) > 1:
        param_list = bytearray(contract.Code.ParameterList)
        param_list[0] = 0

    verification_contract = Contract.Create(reedeem_script, param_list,
                                            pubkey_script_hash)

    address = verification_contract.Address

    wallet.AddContract(verification_contract)

    print(f"Added contract address {address} to wallet")
    return verification_contract
示例#5
0
    async def AddTransactionLoop(self):
        #        self.new_tx_event.wait()

        self.__log.debug("Running add transaction loop")
        while self._disposed == 0:
            transactions = []

            #lock temppool
            #if len(self._temppool == 0): continue
            transactions = list(self._temppool)
            self._temppool = []
            #endlock

            verified = set()
            #lock mempool

            transactions = [
                tx for tx in transactions if not tx.Hash() in _mempool
                and not Blockchain.Default().ContainsTransaction(tx.Hash())
            ]

            if len(transactions):
                mempool_current = [v for k, v in _mempool]
                for tx in transactions:
                    if tx.Verify(mempool_current + transactions):
                        verified.add(tx)
                for tx in verified:
                    _mempool[tx.Hash()] = tx

                self.CheckMemPool()
            #endlock

            await self.RelayDirectly(verified)

            if self.InventoryReceived is not None:
                [self.InventoryReceived.on_change(tx) for tx in verified]
示例#6
0
    def show_block(self, args):
        item = get_arg(args)
        txarg = get_arg(args, 1)
        if item is not None:
            block = Blockchain.Default().GetBlock(item)

            if block is not None:

                bjson = json.dumps(block.ToJson(), indent=4)
                tokens = [(Token.Number, bjson)]
                print_tokens(tokens, self.token_style)
                print('\n')
                if txarg and 'tx' in txarg:

                    #                    with open("b_1445025.txt",'w') as myfile:
                    #                        for tx in block.FullTransactions:
                    #                            myfile.write(json.dumps(tx.ToJson(), indent=4))
                    for tx in block.FullTransactions:
                        print(json.dumps(tx.ToJson(), indent=4))

            else:
                print("could not locate block %s" % item)
        else:
            print("please specify a block")
示例#7
0
    def format_notifications(self, request, notifications, show_none=False):
        notif_len = len(notifications)
        page_len = 500
        page = 0
        message = ''
        if b'page' in request.args:
            try:
                page = int(request.args[b'page'][0])
            except Exception as e:
                print("could not get page: %s" % e)

        start = page_len * page
        end = start + page_len

        if start > notif_len:
            message = 'page greater than result length'

        notifications = notifications[start:end]

        return json.dumps(
            {
                'current_height':
                Blockchain.Default().Height,
                'message':
                message,
                'total':
                notif_len,
                'results':
                None if show_none else [n.ToJson() for n in notifications],
                'page':
                page,
                'page_len':
                page_len
            },
            indent=4,
            sort_keys=True)
示例#8
0
def main():

    settings.setup('protocol.coz.json')
    # Setup the blockchain
    blockchain = LevelDBBlockchain(settings.LEVELDB_PATH)
    Blockchain.RegisterBlockchain(blockchain)
    dbloop = task.LoopingCall(Blockchain.Default().PersistBlocks)
    dbloop.start(.1)
    NodeLeader.Instance().Start()

    # Disable smart contract events for external smart contracts
    settings.set_log_smart_contract_events(False)

    # Start a thread with custom code
    d = threading.Thread(target=custom_background_code)
    d.setDaemon(
        True
    )  # daemonizing the thread will kill it when the main thread is quit
    d.start()

    # Run all the things (blocking call)
    logger.info("Everything setup and running. Waiting for events...")
    reactor.run()
    logger.info("Shutting down.")
示例#9
0
    def height_check(self):
        last_height = 0
        neo = self.Wallet.GetBalance(self.Wallet.GetCoinAssets()[0])
        gas = self.Wallet.GetBalance(self.Wallet.GetCoinAssets()[1])

        while (Blockchain.Default().HeaderHeight - last_height) > 10:
            print('Updating Height...')
            last_height = Blockchain.Default().HeaderHeight
            sleep(5)

        print('Wallet Height: ', self.Wallet._current_height)
        print('Blockchain Height: ', Blockchain.Default().Height)
        print('Header Height: ', Blockchain.Default().HeaderHeight)
        print('Gas Balance: ', gas)

        if self.Wallet._current_height <= Blockchain.Default(
        ).Height - 20 or gas.ToInt() == 0:

            self.Wallet.Rebuild()
            while self.Wallet._current_height < Blockchain.Default(
            ).Height - 2:
                print('Rebuilding Wallet..')
                sleep(5)
示例#10
0
    def test_peer_adding(self):
        leader = NodeLeader.Instance()
        Blockchain.Default()._block_cache = {'hello': 1}

        def mock_call_later(delay, method, *args):
            method(*args)

        def mock_connect_tcp(host, port, factory, timeout=120):
            node = NeoNode()
            node.endpoint = Endpoint(host, port)
            leader.AddConnectedPeer(node)
            return node

        def mock_disconnect(peer):
            return True

        def mock_send_msg(node, message):
            return True

        settings.set_max_peers(len(settings.SEED_LIST))

        with patch('twisted.internet.reactor.connectTCP', mock_connect_tcp):
            with patch('twisted.internet.reactor.callLater', mock_call_later):
                with patch('neo.Network.NeoNode.NeoNode.Disconnect',
                           mock_disconnect):
                    with patch(
                            'neo.Network.NeoNode.NeoNode.SendSerializedMessage',
                            mock_send_msg):

                        leader.Start()
                        self.assertEqual(len(leader.Peers),
                                         len(settings.SEED_LIST))

                        # now test adding another
                        leader.RemoteNodePeerReceived('hello.com', 1234, 6)

                        # it shouldnt add anything so it doesnt go over max connected peers
                        self.assertEqual(len(leader.Peers),
                                         len(settings.SEED_LIST))

                        # test adding peer
                        peer = NeoNode()
                        peer.endpoint = Endpoint('hellloo.com', 12344)
                        leader.ADDRS.append('hellloo.com:12344')
                        leader.AddConnectedPeer(peer)
                        self.assertEqual(len(leader.Peers),
                                         len(settings.SEED_LIST))

                        # now get a peer
                        peer = leader.Peers[0]

                        leader.RemoveConnectedPeer(peer)

                        self.assertEqual(len(leader.Peers),
                                         len(settings.SEED_LIST) - 1)
                        self.assertEqual(len(leader.ADDRS),
                                         len(settings.SEED_LIST))

                        # now test adding another
                        leader.RemoteNodePeerReceived('hello.com', 1234, 6)

                        self.assertEqual(len(leader.Peers),
                                         len(settings.SEED_LIST))

                        # now if we remove all peers, it should restart
                        peers = leader.Peers[:]
                        for peer in peers:
                            leader.RemoveConnectedPeer(peer)

                        # test reset
                        leader.ResetBlockRequestsAndCache()
                        self.assertEqual(Blockchain.Default()._block_cache, {})
示例#11
0
def main():
    parser = argparse.ArgumentParser()

    group = parser.add_mutually_exclusive_group(required=True)
    group.add_argument("-m", "--mainnet", action="store_true", default=False,
                       help="Use MainNet instead of the default TestNet")
    group.add_argument("-t", "--testnet", action="store_true", default=False,
                       help="Use TestNett instead of the default TestNet")
    group.add_argument("-p", "--privnet", action="store_true", default=False,
                       help="Use PrivNet instead of the default TestNet")
    group.add_argument("--coznet", action="store_true", default=False,
                       help="Use the CoZ network instead of the default TestNet")
    group.add_argument("-c", "--config", action="store", help="Use a specific config file")

    parser.add_argument("--port-rpc", type=int, help="port to use for the json-rpc api (eg. 10332)")
    parser.add_argument("--port-rest", type=int, help="port to use for the rest api (eg. 80)")

    args = parser.parse_args()

    if not args.port_rpc and not args.port_rest:
        print("Error: specify at least one of --port-rpc / --port-rest")
        parser.print_help()
        return

    if args.port_rpc == args.port_rest:
        print("Error: --port-rpc and --port-rest cannot be the same")
        parser.print_help()
        return

    # Setup depending on command line arguments. By default, the testnet settings are already loaded.
    if args.config:
        settings.setup(args.config)
    elif args.mainnet:
        settings.setup_mainnet()
    elif args.testnet:
        settings.setup_testnet()
    elif args.privnet:
        settings.setup_privnet()
    elif args.coznet:
        settings.setup_coznet()

    # Write a PID file to easily quit the service
    write_pid_file()

    # Instantiate the blockchain and subscribe to notifications
    blockchain = LevelDBBlockchain(settings.LEVELDB_PATH)
    Blockchain.RegisterBlockchain(blockchain)
    dbloop = task.LoopingCall(Blockchain.Default().PersistBlocks)
    dbloop.start(.1)

    # Disable logging smart contract events
    settings.set_log_smart_contract_events(False)

    # Start the notification db instance
    ndb = NotificationDB.instance()
    ndb.start()

    # Start a thread with custom code
    d = threading.Thread(target=custom_background_code)
    d.setDaemon(True)  # daemonizing the thread will kill it when the main thread is quit
    d.start()

    # Run
    reactor.suggestThreadPoolSize(15)
    NodeLeader.Instance().Start()

    host = "0.0.0.0"

    if args.port_rpc:
        logger.info("Starting json-rpc api server on http://%s:%s" % (host, args.port_rpc))
        api_server_rpc = JsonRpcApi(args.port_rpc)
        endpoint_rpc = "tcp:port={0}:interface={1}".format(args.port_rpc, host)
        endpoints.serverFromString(reactor, endpoint_rpc).listen(Site(api_server_rpc.app.resource()))

    if args.port_rest:
        logger.info("Starting notification api server on http://%s:%s" % (host, args.port_rest))
        api_server_rest = NotificationRestApi()
        endpoint_rest = "tcp:port={0}:interface={1}".format(args.port_rest, host)
        endpoints.serverFromString(reactor, endpoint_rest).listen(Site(api_server_rest.app.resource()))

    app = Klein()
    app.run(host, 9999)
示例#12
0
    def run(self):

        dbloop = task.LoopingCall(Blockchain.Default().PersistBlocks)
        dbloop.start(.1)

        Blockchain.Default().PersistBlocks()

        self.node_leader = NodeLeader.Instance()

        tokens = [(Token.Neo, 'NEO'), (Token.Default, ' cli. Type '),
                  (Token.Command, "'help' "),
                  (Token.Default, 'to get started')]
        print_tokens(tokens, self.token_style)
        print("\n")

        while self.go_on:

            result = prompt("neo> ",
                            completer=self.completer,
                            history=self.history,
                            get_bottom_toolbar_tokens=self.get_bottom_toolbar,
                            style=self.token_style)

            command, arguments = self.parse_result(result)

            if command is not None and len(command) > 0:
                command = command.lower()

                if command == 'quit' or command == 'exit':
                    self.quit()
                elif command == 'help':
                    self.help()
                elif command == 'block':
                    self.show_block(arguments)
                elif command == 'tx':
                    self.show_tx(arguments)
                elif command == 'header':
                    self.show_header(arguments)
                elif command == 'account':
                    self.show_account_state(arguments)
                elif command == 'contract':
                    self.show_contract_state(arguments)
                elif command == 'sc':
                    self.show_spent_coins(arguments)
                elif command == 'mem':
                    self.show_mem()
                elif command == 'nodes' or command == 'node':
                    self.show_nodes()
                elif command == 'state':
                    self.show_state()
                elif command == 'config':
                    self.configure(arguments)
                elif command == 'pause' or command == 'unpause' or command == 'resume':
                    self.toggle_pause()
                elif command == None:
                    print('please specify a command')
                else:
                    print("command %s not found" % command)

            else:
                pass
示例#13
0
class PromptInterface(object):

    go_on = True

    completer = WordCompleter([
        'block', 'tx', 'header', 'mem', 'help', 'state', 'node', 'exit',
        'quit', 'config', 'db', 'log'
    ])

    commands = [
        'quit',
        'help',
        'block {index/hash}',
        'header {index/hash}',
        'tx {hash}',
        'mem',
        'nodes',
        'state',
        'config {node, db} int int'
        'config log on/off'
        'pause',
    ]

    token_style = style_from_dict({
        Token.Command: '#ff0066',
        Token.Neo: '#0000ee',
        Token.Default: '#00ee00',
        Token.Number: "#ffffff",
    })

    history = InMemoryHistory()

    start_height = Blockchain.Default().Height
    start_dt = datetime.datetime.utcnow()

    node_leader = None

    paused = False

    def paused_loop(self):

        while self.paused:
            #            self.__log.debug("paused...")
            time.sleep(1)

    def get_bottom_toolbar(self, cli=None):
        try:
            return [(Token.Command, 'Progress: '),
                    (Token.Number, str(Blockchain.Default().Height)),
                    (Token.Neo, '/'),
                    (Token.Number, str(Blockchain.Default().HeaderHeight - 1))]
        except Exception as e:
            print("couldnt get toolbar: %s " % e)
            return []

    def quit(self):
        print('Shutting down.  This may take a bit...')
        self.go_on = False
        self.paused = False
        Blockchain.Default().Dispose()
        reactor.stop()
        self.node_leader.Shutdown()

    def help(self):
        tokens = []
        for c in self.commands:
            tokens.append((Token.Command, "%s\n" % c))
        print_tokens(tokens, self.token_style)

    def toggle_pause(self):
        if self.paused:
            self.paused = not self.paused
            #            reactor.run()
            print("resusiming execution")

        else:
            self.paused = not self.paused
            print('pausing execution!')
            reactor.callLater(1, self.paused_loop)

    def show_state(self):
        height = Blockchain.Default().Height
        headers = Blockchain.Default().HeaderHeight - 1

        diff = height - self.start_height
        now = datetime.datetime.utcnow()
        difftime = now - self.start_dt

        mins = difftime / datetime.timedelta(minutes=1)

        bpm = 0
        if diff > 0 and mins > 0:
            bpm = diff / mins

        out = 'Progress: %s / %s\n' % (height, headers)
        out += 'Block Cache length %s\n' % Blockchain.Default().BlockCacheCount
        out += 'Blocks since program start %s\n' % diff
        out += 'Time elapsed %s mins\n' % mins
        out += 'blocks per min %s \n' % bpm
        out += "Node Req Part, Max: %s %s\n" % (self.node_leader.BREQPART,
                                                self.node_leader.BREQMAX)
        out += "DB Cache Lim, Miss Lim %s %s\n" % (
            Blockchain.Default().CACHELIM, Blockchain.Default().CMISSLIM)
        tokens = [(Token.Number, out)]
        print_tokens(tokens, self.token_style)

    def show_nodes(self):
        if self.node_leader and len(self.node_leader.Peers):
            out = ''
            for peer in self.node_leader.Peers:
                out += 'Peer %s - IO: %s\n' % (peer.Name(), peer.IOStats())
            print_tokens([(Token.Number, out)], self.token_style)
        else:
            print('Not connected yet\n')

    def show_block(self, args):
        item = self.get_arg(args)
        txarg = self.get_arg(args, 1)
        if item is not None:
            block = Blockchain.Default().GetBlock(item)

            if block is not None:
                bjson = json.dumps(block.ToJson(), indent=4)
                tokens = [(Token.Number, bjson)]
                print_tokens(tokens, self.token_style)
                print('\n')
                if txarg and 'tx' in txarg:

                    for tx in block.Transactions:
                        self.show_tx([tx])

            else:
                print("could not locate block %s" % item)
        else:
            print("please specify a block")

    def show_header(self, args):
        item = self.get_arg(args)
        if item is not None:
            header = Blockchain.Default().GetHeaderBy(item)
            if header is not None:
                print(json.dumps(header.ToJson(), indent=4))
            else:
                print("could not locate Header %s \n" % item)
        else:
            print("please specify a header")

    def show_tx(self, args):
        item = self.get_arg(args)
        if item is not None:
            try:
                tx, height = Blockchain.Default().GetTransaction(item)
                if height > -1:

                    bjson = json.dumps(tx.ToJson(), indent=4)
                    tokens = [(Token.Command, bjson)]
                    print_tokens(tokens, self.token_style)
                    print('\n')
            except Exception as e:
                print("Could not find transaction with id %s " % item)
                print(
                    "Please specify a tx hash like 'db55b4d97cf99db6826967ef4318c2993852dff3e79ec446103f141c716227f6'"
                )
        else:
            print("please specify a tx hash")

    def show_account_state(self, args):
        item = self.get_arg(args)
        print("account to show %s " % item)

        if item is not None:
            account = Blockchain.Default().GetAccountState(
                item, print_all_accounts=True)

            if account is not None:
                bjson = json.dumps(account.ToJson(), indent=4)
                tokens = [(Token.Number, bjson)]
                print_tokens(tokens, self.token_style)
                print('\n')
            else:
                print("account %s not found" % item)
        else:
            print("please specify an account address")

    def show_contract_state(self, args):
        item = self.get_arg(args)

        if item is not None:

            if item.lower() == 'all':
                contracts = Blockchain.Default().ShowAllContracts()
                print("contracts: %s " % contracts)
            else:
                contract = Blockchain.Default().GetContract(item)
                if contract is not None:
                    bjson = json.dumps(contract.ToJson(), indent=4)
                    tokens = [(Token.Number, bjson)]
                    print_tokens(tokens, self.token_style)
                    print('\n')
        else:
            print("please specify a contract")

    def show_spent_coins(self, args):
        item = self.get_arg(args)

        if item is not None:
            if item.lower() == 'all':
                coins = Blockchain.Default().GetAllSpentCoins()
                print("coins %s " % coins)
            else:

                coin = Blockchain.Default().GetSpentCoins(item)
                if coin is not None:
                    bjson = json.dumps(coin.ToJson(), indent=4)
                    tokens = [(Token.Number, bjson)]
                    print_tokens(tokens, self.token_style)
                    print("\n")
        else:
            print("please specify a tx hash")

    def show_mem(self):
        total = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
        totalmb = total / 1000000
        out = "Total: %s MB\n" % totalmb
        out += "total buffers %s\n" % StreamManager.TotalBuffers()
        print_tokens([(Token.Number, out)], self.token_style)

    def configure(self, args):
        what = self.get_arg(args)

        if what == 'node':
            c1 = self.get_arg(args, 1, convert_to_int=True)
            c2 = self.get_arg(args, 2, convert_to_int=True)

            if not c1:
                print("please provide settings. arguments must be integers")

            if c1 is not None and c1 > 1:
                if c1 > 200:
                    c1 = 200
                    print("Node request part must be less than 201")
                self.node_leader.BREQPART = c1
                print("Set Node Request Part to %s " % c1)
            if c2 is not None and c2 >= self.node_leader.BREQPART:
                self.node_leader.BREQMAX = c2
                print("Set Node Request Max to %s " % c2)
            self.show_state()
        elif what == 'db':
            c1 = self.get_arg(args, 1, convert_to_int=True)
            c2 = self.get_arg(args, 2, convert_to_int=True)
            if c1 is not None and c1 > 1:
                Blockchain.Default().CACHELIM = c1
                print("Set DB Cache Limit to %s " % c1)
            if c2 is not None and c2 >= self.node_leader.BREQPART:
                Blockchain.Default().CMISSLIM = c2
                print("Set DB Cache Miss Limit %s " % c2)
            self.show_state()
        elif what == 'log' or what == 'logs':
            c1 = self.get_arg(args, 1).lower()
            if c1 is not None:
                if c1 == 'on' or c1 == '1':
                    print("turning on logging")
                    logger = logging.getLogger()
                    logger.setLevel(logging.DEBUG)
                if c1 == 'off' or c1 == '0':
                    print("turning off logging")
                    logger = logging.getLogger()
                    logger.setLevel(logging.ERROR)

            else:
                print("cannot configure log.  Please specify on or off")
        else:
            print("cannot configure %s " % what)
            print(
                "Try 'config node 100 1000' or config db 1000 4' or config log on/off"
            )

    def get_arg(self, arguments, index=0, convert_to_int=False):
        try:
            arg = arguments[index]
            if convert_to_int:
                return int(arg)
            return arg
        except Exception as e:
            pass
        return None

    def parse_result(self, result):
        if len(result):
            commandParts = [s for s in result.split()]
            return commandParts[0], commandParts[1:]
        return None, None

    def run(self):

        dbloop = task.LoopingCall(Blockchain.Default().PersistBlocks)
        dbloop.start(.1)

        Blockchain.Default().PersistBlocks()

        self.node_leader = NodeLeader.Instance()

        tokens = [(Token.Neo, 'NEO'), (Token.Default, ' cli. Type '),
                  (Token.Command, "'help' "),
                  (Token.Default, 'to get started')]
        print_tokens(tokens, self.token_style)
        print("\n")

        while self.go_on:

            result = prompt("neo> ",
                            completer=self.completer,
                            history=self.history,
                            get_bottom_toolbar_tokens=self.get_bottom_toolbar,
                            style=self.token_style)

            command, arguments = self.parse_result(result)

            if command is not None and len(command) > 0:
                command = command.lower()

                if command == 'quit' or command == 'exit':
                    self.quit()
                elif command == 'help':
                    self.help()
                elif command == 'block':
                    self.show_block(arguments)
                elif command == 'tx':
                    self.show_tx(arguments)
                elif command == 'header':
                    self.show_header(arguments)
                elif command == 'account':
                    self.show_account_state(arguments)
                elif command == 'contract':
                    self.show_contract_state(arguments)
                elif command == 'sc':
                    self.show_spent_coins(arguments)
                elif command == 'mem':
                    self.show_mem()
                elif command == 'nodes' or command == 'node':
                    self.show_nodes()
                elif command == 'state':
                    self.show_state()
                elif command == 'config':
                    self.configure(arguments)
                elif command == 'pause' or command == 'unpause' or command == 'resume':
                    self.toggle_pause()
                elif command == None:
                    print('please specify a command')
                else:
                    print("command %s not found" % command)

            else:
                pass
示例#14
0
def construct_send_tx(wallet, arguments):
        from_address = arguments['from']
        to_send = arguments['asset']
        address_to = arguments['to']
        amount = arguments['amount']

        user_tx_attributes = arguments.get('attrs', [])

        assetId = get_asset_id(wallet, to_send)

        if assetId is None:
            raise Exception("Asset id not found")

        scripthash_to = lookup_addr_str(wallet, address_to)
        if scripthash_to is None:
            raise Exception("invalid address")

        scripthash_from = None

        if from_address is not None:
            scripthash_from = lookup_addr_str(wallet, from_address)

        if type(assetId) is NEP5Token:
            raise Exception("cannot transfer token in this version")

        f8amount = Fixed8.TryParse(amount, require_positive=True)
        if f8amount is None:
            raise Exception("invalid amount format")

        if type(assetId) is UInt256 and f8amount.value % pow(10, 8 - Blockchain.Default().GetAssetState(assetId.ToBytes()).Precision) != 0:
            raise Exception("incorrect amount precision")

        fee = Fixed8.Zero()

        output = TransactionOutput(AssetId=assetId, Value=f8amount, script_hash=scripthash_to)
        tx = ContractTransaction(outputs=[output])
        ttx = wallet.MakeTransaction(tx=tx,
                                     fee=fee,
                                     from_addr=scripthash_from)


        if ttx is None:
            raise Exception("no funds")

        standard_contract = wallet.GetStandardAddress()

        if scripthash_from is not None:
            signer_contract = wallet.GetContract(scripthash_from)
        else:
            signer_contract = wallet.GetContract(standard_contract)

        if not signer_contract.IsMultiSigContract:

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

        # insert any additional user specified tx attributes
        tx.Attributes = tx.Attributes + user_tx_attributes


        context = ContractParametersContext(tx, isMultiSig=signer_contract.IsMultiSigContract)
       

        logger.info(context.ToJson())
        logger.info('*'*60)
        logger.info(tx.ToJson())
#        import pdb
#        pdb.set_trace()
        ms = StreamManager.GetStream()
        writer = BinaryWriter(ms)
        tx.Serialize(writer)
        ms.flush()
        binary_tx = ms.ToArray()
        print(tx)
        return {'context': context.ToJson(), 'tx': binary_tx.decode()}
示例#15
0
def construct_deploy_tx(wallet, params):
    params = params[0]
    from_addr = params['from_addr']
    # load_smart_contract
    contract_params = bytearray(binascii.unhexlify(params['contract_params']))
    return_type = bytearray(binascii.unhexlify(params['return_type']))
    
    contract_properties = 0
    if params.get('needs_storage', True):
        contract_properties += ContractPropertyState.HasStorage
    if params.get('needs_dynamic_invoke', False):
        contract_properties += ContractPropertyState.HasDynamicInvoke

    script = binascii.unhexlify(params['bin'])

    function_code = FunctionCode(
            script = script,
            param_list = contract_params,
            return_type = return_type,
            contract_properties = contract_properties,
    )

    if Blockchain.Default().GetContract(function_code.ScriptHash().To0xString()):
        raise Exception('contract already exists')

    # GatherContractDetails
    details = params['details']
    name = details['name']
    version = details['version']
    author = details['author']
    email = details['email']
    description = details['description']

    contract_script = generate_deploy_script(
            function_code.Script,
            name,
            version,
            author,
            email,
            description,
            function_code.ContractProperties,
            function_code.ReturnType,
            function_code.ParameterList,
    )

    # test_invoke    
    bc = GetBlockchain()
    sn = bc._db.snapshot()
    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)


    tx = InvocationTransaction()
    tx.outputs = []
    tx.inputs = []
    tx.Version = 1
    tx.scripts = []
    tx.Script = binascii.unhexlify(contract_script)

    script_table = CachedScriptTable(contracts)
    service = StateMachine(accounts, validators, assets, contracts, storages, None)
    contract = wallet.GetDefaultContract()
    tx.Attributes = [TransactionAttribute(usage=TransactionAttributeUsage.Script, data=Crypto.ToScriptHash(contract.Script, unhex=False).Data)]
    tx = wallet.MakeTransaction(tx=tx)

    engine = ApplicationEngine(
            trigger_type=TriggerType.Application,
            container=tx,
            table=script_table,
            service=service,
            gas=tx.Gas,
            testMode=True
    )   
    engine.LoadScript(tx.Script, False)
    success = engine.Execute()
    if not success:
        raise Exception('exec failed')
    
    service.ExecutionCompleted(engine, success)

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

    net_fee = None
    tx_gas = None

    if consumed <= Fixed8.Zero():
        net_fee = Fixed8.FromDecimal(.0001)
        tx_gas = Fixed8.Zero()
    else:
        tx_gas = consumed
        net_fee = Fixed8.Zero()
    tx.Gas = tx_gas
    tx.outputs = []
    tx.Attributes = []

    # InvokeContract
    from_addr = lookup_addr_str(wallet, from_addr)
    tx = wallet.MakeTransaction(tx=tx, fee=net_fee, use_standard=True, from_addr=from_addr)
    if tx is None:
        raise Exception("no gas")


    context = ContractParametersContext(tx)
    ms = StreamManager.GetStream()
    writer = BinaryWriter(ms)
    tx.Serialize(writer)
    ms.flush()
    binary_tx = ms.ToArray()
    return {'context': context.ToJson(), 'tx': binary_tx.decode(), 'hash': function_code.ScriptHash().To0xString()}
示例#16
0
    def Asset_Create(self, engine):

        tx = engine.ScriptContainer

        asset_type = int(engine.EvaluationStack.Pop().GetBigInteger())

        if asset_type not in AssetType.AllTypes() or \
                asset_type == AssetType.CreditFlag or \
                asset_type == AssetType.DutyFlag or \
                asset_type == AssetType.GoverningToken or \
                asset_type == AssetType.UtilityToken:

            return False

        if len(engine.EvaluationStack.Peek().GetByteArray()) > 1024:
            return False

        name = engine.EvaluationStack.Pop().GetByteArray().decode('utf-8')

        amount = Fixed8(engine.EvaluationStack.Pop().GetBigInteger())

        if amount == Fixed8.Zero() or amount < Fixed8.NegativeSatoshi():
            return False

        if asset_type == AssetType.Invoice and amount != Fixed8.NegativeSatoshi(
        ):
            return False

        precision = int(engine.EvaluationStack.Pop().GetBigInteger())

        if precision > 8:
            return False

        if asset_type == AssetType.Share and precision != 0:
            return False

        if amount != Fixed8.NegativeSatoshi() and amount.value % pow(
                10, 8 - precision) != 0:
            return False

        ownerData = engine.EvaluationStack.Pop().GetByteArray()

        owner = ECDSA.decode_secp256r1(ownerData, unhex=False).G

        if owner.IsInfinity:
            return False

        if not self.CheckWitnessPubkey(engine, owner):
            logger.error("check witness false...")
            return False

        admin = UInt160(data=engine.EvaluationStack.Pop().GetByteArray())

        issuer = UInt160(data=engine.EvaluationStack.Pop().GetByteArray())

        new_asset = AssetState(asset_id=tx.Hash,
                               asset_type=asset_type,
                               name=name,
                               amount=amount,
                               available=Fixed8.Zero(),
                               precision=precision,
                               fee_mode=0,
                               fee=Fixed8.Zero(),
                               fee_addr=UInt160(),
                               owner=owner,
                               admin=admin,
                               issuer=issuer,
                               expiration=Blockchain.Default().Height + 1 +
                               2000000,
                               is_frozen=False)

        asset = self._assets.GetOrAdd(tx.Hash.ToBytes(), new_asset)

        # print("*****************************************************")
        # print("CREATED ASSET %s " % tx.Hash.ToBytes())
        # print("*****************************************************")
        engine.EvaluationStack.PushT(StackItem.FromInterface(asset))

        return True
示例#17
0
def process_transaction(wallet,
                        contract_tx,
                        scripthash_from=None,
                        scripthash_change=None,
                        fee=None,
                        owners=None,
                        user_tx_attributes=None):
    try:
        tx = wallet.MakeTransaction(tx=contract_tx,
                                    change_address=scripthash_change,
                                    fee=fee,
                                    from_addr=scripthash_from)
    except ValueError:
        print(
            "Insufficient funds. No unspent outputs available for building the transaction.\n"
            "If you are trying to sent multiple transactions in 1 block, then make sure you have enough 'vouts'\n."
            "Use `wallet unspent` and `wallet address split`, or wait until the first transaction is processed before sending another."
        )
        return
    except TXFeeError as e:
        print(e)
        return

    if tx is None:
        logger.debug("insufficient funds")
        return

    try:
        print("Validate your transaction details")
        print("-" * 33)
        input_coinref = wallet.FindCoinsByVins(tx.inputs)[0]
        source_addr = input_coinref.Address
        for order in tx.outputs:
            dest_addr = order.Address
            value = order.Value.ToString()  # fixed8
            if order.AssetId == Blockchain.Default().SystemShare().Hash:
                asset_name = 'NEO'
            else:
                asset_name = 'GAS'

            if source_addr != dest_addr:
                print(
                    f"Sending {value} {asset_name} from {source_addr} to {dest_addr}"
                )
            else:
                print(
                    f"Returning {value} {asset_name} as change to {dest_addr}")
        print(" ")
        print("Enter your password to send to the network")

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

        standard_contract = wallet.GetStandardAddress()

        if scripthash_from is not None:
            signer_contract = wallet.GetContract(scripthash_from)
        else:
            signer_contract = wallet.GetContract(standard_contract)

        if not signer_contract.IsMultiSigContract and owners is None:
            data = standard_contract.Data
            tx.Attributes = [
                TransactionAttribute(usage=TransactionAttributeUsage.Script,
                                     data=data)
            ]

        # insert any additional user specified tx attributes
        tx.Attributes = tx.Attributes + user_tx_attributes

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

        context = ContractParametersContext(
            tx, isMultiSig=signer_contract.IsMultiSigContract)
        wallet.Sign(context)

        if owners:
            owners = list(owners)
            gather_signatures(context, tx, owners)

        if context.Completed:

            tx.scripts = context.GetScripts()
            relayed = NodeLeader.Instance().Relay(tx)

            if relayed:
                wallet.SaveTransaction(tx)

                print("Relayed Tx: %s " % tx.Hash.ToString())
                return tx
            else:

                print("Could not relay tx %s " % tx.Hash.ToString())

        else:
            print(
                "Transaction initiated, but the signature is incomplete. Use the `sign` command with the information below to complete signing."
            )
            print(json.dumps(context.ToJson(), separators=(',', ':')))
            return

    except Exception as e:
        print("Could not send: %s " % e)
        traceback.print_stack()
        traceback.print_exc()

    return
    def run(self):
        dbloop = task.LoopingCall(Blockchain.Default().PersistBlocks)
        dbloop.start(.1)
        Blockchain.Default().PersistBlocks()

        while Blockchain.Default().Height < 2:
            print("Waiting for wallet to sync...")
            time.sleep(1)

        print("Creating Wallet...")
        self.wallet = UserWallet.Create(path=self.wallet_fn,
                                        password=self.wallet_pwd)
        self.wallet.ProcessBlocks()

        # Extract infos from wallet
        contract = self.wallet.GetDefaultContract()
        key = self.wallet.GetKey(contract.PublicKeyHash)
        address = key.GetAddress()
        wif = key.Export()
        print("- Address:", address)
        print("- WIF key:", wif)
        self.wallet = None

        # Claim initial NEO
        self.claim_initial_neo(address)

        # Open wallet again
        self.wallet = UserWallet.Open(self.wallet_fn, self.wallet_pwd)
        self._walletdb_loop = task.LoopingCall(self.wallet.ProcessBlocks)
        self._walletdb_loop.start(1)

        print("\nWait %s min before claiming GAS." % self.min_wait)
        time.sleep(60 * self.min_wait)

        print("\nSending NEO to own wallet...")
        tx = construct_and_send(None,
                                self.wallet, ["neo", address, "100000000"],
                                prompt_password=False)
        if not tx:
            print("Something went wrong, no tx.")
            return

        # Wait until transaction is on blockchain
        self.wait_for_tx(tx)

        print("Claiming the GAS...")
        claim_tx, relayed = ClaimGas(self.wallet, require_password=False)
        self.wait_for_tx(claim_tx)

        # Finally, need to rebuild the wallet
        self.wallet.Rebuild()

        print("\nAll done!")
        print("- WIF key: %s" % wif)
        print("- Wallet file: %s" % self.wallet_fn)
        print("- Wallet pwd: %s" % self.wallet_pwd)

        if self.wif_fn:
            with open(self.wif_fn, "w") as f:
                f.write(wif)

        self.quit()
示例#19
0
    def run(self):
        dbloop = task.LoopingCall(Blockchain.Default().PersistBlocks)
        dbloop.start(.1)

        Blockchain.Default().PersistBlocks()

        while Blockchain.Default().Height < 2:
            print("Waiting for prompt to sync...")
            time.sleep(1)

        tokens = [(Token.Neo, 'NEO'), (Token.Default, ' cli. Type '),
                  (Token.Command, "'help' "),
                  (Token.Default, 'to get started')]

        print_tokens(tokens, self.token_style)
        print("\n")

        timebase = time.time()

        while self.go_on:

            try:
                if len(self.mycommands) > 0:
                    timenow = time.time()
                    if timenow - timebase > 3:  #wait 3 seconds
                        timebase = timenow
                        result = self.mycommands.pop()
                    else:
                        time.sleep(0.5)  # slow refresh
                        continue
                    #time.sleep(3)
                else:
                    result = prompt(
                        "neo> ",
                        completer=self.get_completer(),
                        history=self.history,
                        get_bottom_toolbar_tokens=self.get_bottom_toolbar,
                        style=self.token_style,
                        refresh_interval=3)
                    # Control-D pressed: quit

                #print("result=",result)
                #print("mycommands ->", self.mycommands)
            except EOFError:
                return self.quit()
            except KeyboardInterrupt:
                # Control-C pressed: do nothing
                continue

            try:
                command, arguments = self.parse_result(result)

                if command is not None and len(command) > 0:
                    command = command.lower()

                    if command == 'quit' or command == 'exit':
                        time.sleep(2)  # consolidate chain
                        self.quit()
                    elif command == 'help':
                        self.help()
                    elif command == 'create':
                        self.do_create(arguments)
                    elif command == 'open':
                        self.do_open(arguments)
                    elif command == 'build':
                        self.do_build(arguments)
                    elif command == 'load_run':
                        self.do_load_n_run(arguments)
                    elif command == 'import':
                        tx = self.do_import(arguments)
                        # Wait until transaction is on blockchain
                        if tx is not None:
                            self.wait_for_tx(tx)
                    elif command == 'export':
                        self.do_export(arguments)
                    elif command == 'wallet':
                        self.show_wallet(arguments)
                    elif command == 'send':
                        tx = self.do_send(arguments)
                        if tx is not None:
                            if tx is not 0:
                                self.wait_for_tx(tx)
                    elif command == 'sign':
                        self.do_sign(arguments)
                    elif command == 'block':
                        self.show_block(arguments)
                    elif command == 'tx':
                        self.show_tx(arguments)
                    elif command == 'header':
                        self.show_header(arguments)
                    elif command == 'account':
                        self.show_account_state(arguments)
                    elif command == 'asset':
                        self.show_asset_state(arguments)
                    elif command == 'contract':
                        tx = self.show_contract_state(arguments)
                    elif command == 'testinvoke':
                        tx = self.test_invoke_contract(arguments)
                        # Wait until transaction is on blockchain
                        if tx is not None:
                            self.wait_for_tx(tx)
                    elif command == 'mem':
                        self.show_mem()
                    elif command == 'nodes' or command == 'node':
                        self.show_nodes()
                    elif command == 'state':
                        self.show_state()
                    elif command == 'debugstorage':
                        self.handle_debug_storage(arguments)
                    elif command == 'config':
                        self.configure(arguments)
                    elif command is None:
                        print('please specify a command')
                    else:
                        print("command %s not found" % command)

            except Exception as e:

                print("could not execute command: %s " % e)
                traceback.print_stack()
                traceback.print_exc()
示例#20
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
示例#21
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
示例#22
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
    except TXFeeError as e:
        print(e)
        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()

            relayed = NodeLeader.Instance().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
示例#23
0
def main():
    parser = argparse.ArgumentParser()

    # Network options
    group_network_container = parser.add_argument_group(
        title="Network options")
    group_network = group_network_container.add_mutually_exclusive_group(
        required=True)
    group_network.add_argument("--mainnet",
                               action="store_true",
                               default=False,
                               help="Use MainNet")
    group_network.add_argument("--testnet",
                               action="store_true",
                               default=False,
                               help="Use TestNet")
    group_network.add_argument("--privnet",
                               action="store_true",
                               default=False,
                               help="Use PrivNet")
    group_network.add_argument("--coznet",
                               action="store_true",
                               default=False,
                               help="Use CozNet")
    group_network.add_argument("--config",
                               action="store",
                               help="Use a specific config file")

    # Ports for RPC and REST api
    group_modes = parser.add_argument_group(title="Mode(s)")
    group_modes.add_argument(
        "--port-rpc",
        type=int,
        help="port to use for the json-rpc api (eg. 10332)")
    group_modes.add_argument("--port-rest",
                             type=int,
                             help="port to use for the rest api (eg. 80)")

    # Advanced logging setup
    group_logging = parser.add_argument_group(title="Logging options")
    group_logging.add_argument("--logfile",
                               action="store",
                               type=str,
                               help="Logfile")
    group_logging.add_argument(
        "--syslog",
        action="store_true",
        help=
        "Log to syslog instead of to log file ('user' is the default facility)"
    )
    group_logging.add_argument(
        "--syslog-local",
        action="store",
        type=int,
        choices=range(0, 7),
        metavar="[0-7]",
        help=
        "Log to a local syslog facility instead of 'user'. Value must be between 0 and 7 (e.g. 0 for 'local0')."
    )
    group_logging.add_argument("--disable-stderr",
                               action="store_true",
                               help="Disable stderr logger")

    # Where to store stuff
    parser.add_argument("--datadir",
                        action="store",
                        help="Absolute path to use for database directories")
    # peers
    parser.add_argument("--maxpeers",
                        action="store",
                        default=5,
                        help="Max peers to use for P2P Joining")

    # host
    parser.add_argument("--host",
                        action="store",
                        type=str,
                        help="Hostname ( for example 127.0.0.1)",
                        default="0.0.0.0")

    # Now parse
    args = parser.parse_args()
    # print(args)

    if not args.port_rpc and not args.port_rest:
        print("Error: specify at least one of --port-rpc / --port-rest")
        parser.print_help()
        return

    if args.port_rpc == args.port_rest:
        print("Error: --port-rpc and --port-rest cannot be the same")
        parser.print_help()
        return

    if args.logfile and (args.syslog or args.syslog_local):
        print("Error: Cannot only use logfile or syslog at once")
        parser.print_help()
        return

    # Setting the datadir must come before setting the network, else the wrong path is checked at net setup.
    if args.datadir:
        settings.set_data_dir(args.datadir)

    # Network configuration depending on command line arguments. By default, the testnet settings are already loaded.
    if args.config:
        settings.setup(args.config)
    elif args.mainnet:
        settings.setup_mainnet()
    elif args.testnet:
        settings.setup_testnet()
    elif args.privnet:
        settings.setup_privnet()
    elif args.coznet:
        settings.setup_coznet()

    if args.maxpeers:
        settings.set_max_peers(args.maxpeers)

    if args.syslog or args.syslog_local is not None:
        # Setup the syslog facility
        if args.syslog_local is not None:
            print("Logging to syslog local%s facility" % args.syslog_local)
            syslog_facility = SysLogHandler.LOG_LOCAL0 + args.syslog_local
        else:
            print("Logging to syslog user facility")
            syslog_facility = SysLogHandler.LOG_USER

        # Setup logzero to only use the syslog handler
        logzero.syslog(facility=syslog_facility)
    else:
        # Setup file logging
        if args.logfile:
            logfile = os.path.abspath(args.logfile)
            if args.disable_stderr:
                print("Logging to logfile: %s" % logfile)
            else:
                print("Logging to stderr and logfile: %s" % logfile)
            logzero.logfile(logfile,
                            maxBytes=LOGFILE_MAX_BYTES,
                            backupCount=LOGFILE_BACKUP_COUNT,
                            disableStderrLogger=args.disable_stderr)

        else:
            print("Logging to stdout and stderr")

    # Disable logging smart contract events
    settings.set_log_smart_contract_events(False)

    # Write a PID file to easily quit the service
    write_pid_file()

    # Setup Twisted and Klein logging to use the logzero setup
    observer = STDLibLogObserver(name=logzero.LOGZERO_DEFAULT_LOGGER)
    globalLogPublisher.addObserver(observer)

    # Instantiate the blockchain and subscribe to notifications
    blockchain = LevelDBBlockchain(settings.chain_leveldb_path)
    Blockchain.RegisterBlockchain(blockchain)
    dbloop = task.LoopingCall(Blockchain.Default().PersistBlocks)
    dbloop.start(.1)

    # Setup twisted reactor, NodeLeader and start the NotificationDB
    reactor.suggestThreadPoolSize(15)
    NodeLeader.Instance().Start()
    NotificationDB.instance().start()

    # Start a thread with custom code
    d = threading.Thread(target=custom_background_code)
    d.setDaemon(
        True
    )  # daemonizing the thread will kill it when the main thread is quit
    d.start()

    if args.port_rpc:
        logger.info("Starting json-rpc api server on http://%s:%s" %
                    (args.host, args.port_rpc))
        api_server_rpc = JsonRpcApi(args.port_rpc)
        endpoint_rpc = "tcp:port={0}:interface={1}".format(
            args.port_rpc, args.host)
        endpoints.serverFromString(reactor, endpoint_rpc).listen(
            Site(api_server_rpc.app.resource()))
#        reactor.listenTCP(int(args.port_rpc), server.Site(api_server_rpc))
#        api_server_rpc.app.run(args.host, args.port_rpc)

    if args.port_rest:
        logger.info("Starting REST api server on http://%s:%s" %
                    (args.host, args.port_rest))
        api_server_rest = RestApi()
        endpoint_rest = "tcp:port={0}:interface={1}".format(
            args.port_rest, args.host)
        endpoints.serverFromString(reactor, endpoint_rest).listen(
            Site(api_server_rest.app.resource()))


#        api_server_rest.app.run(args.host, args.port_rest)

    reactor.run()

    # After the reactor is stopped, gracefully shutdown the database.
    logger.info("Closing databases...")
    NotificationDB.close()
    Blockchain.Default().Dispose()
    NodeLeader.Instance().Shutdown()
示例#24
0
    def test_show_notifications(self):
        # setup
        wallet_1_addr = 'AJQ6FoaSXDFzA6wLnyZ1nFN7SGSN2oNTc3'

        # test with no NotificationDB
        with patch(
                'neo.Implementations.Notifications.NotificationDB.NotificationDB.instance',
                return_value=None):
            args = ['notifications', wallet_1_addr]
            res = CommandShow().execute(args)
            self.assertFalse(res)

        # test with no input
        args = ['notifications']
        res = CommandShow().execute(args)
        self.assertFalse(res)

        # good test with address
        args = ['notifications', wallet_1_addr]
        res = CommandShow().execute(args)
        self.assertTrue(res)
        self.assertEqual(len(res), 1)
        jsn = res[0].ToJson()
        self.assertEqual(jsn['notify_type'], 'transfer')
        self.assertEqual(jsn['addr_from'], wallet_1_addr)

        # test an address with no notifications
        args = ['notifications', 'AZiE7xfyJALW7KmADWtCJXGGcnduYhGiCX']
        res = CommandShow().execute(args)
        self.assertFalse(res)

        # good test with contract
        contract_hash = "31730cc9a1844891a3bafd1aa929a4142860d8d3"
        args = ['notifications', contract_hash]
        res = CommandShow().execute(args)
        self.assertTrue(res)
        self.assertEqual(len(res), 1)
        jsn = res[0].ToJson()
        self.assertEqual(jsn['notify_type'], 'transfer')
        self.assertIn(contract_hash, jsn['contract'])

        # good test with contract 0x hash
        contract_hash = "0x31730cc9a1844891a3bafd1aa929a4142860d8d3"
        args = ['notifications', contract_hash]
        res = CommandShow().execute(args)
        self.assertTrue(res)
        self.assertEqual(len(res), 1)
        jsn = res[0].ToJson()
        self.assertEqual(jsn['notify_type'], 'transfer')
        self.assertEqual(contract_hash, jsn['contract'])

        # test contract not on the blockchain
        contract_hash = "3a4acd3647086e7c44398aac0349802e6a171129"  # NEX token hash
        args = ['notifications', contract_hash]
        res = CommandShow().execute(args)
        self.assertFalse(res)

        # good test with block index
        args = ['notifications', "12337"]
        res = CommandShow().execute(args)
        self.assertTrue(res)
        self.assertEqual(len(res), 1)
        jsn = res[0].ToJson()
        self.assertEqual(jsn['notify_type'], 'transfer')
        self.assertEqual(jsn['block'], 12337)

        # test block with no notifications
        args = ['notifications', "1"]
        res = CommandShow().execute(args)
        self.assertFalse(res)

        # test bad block
        index = Blockchain.Default().Height + 1
        args = ['notifications', str(index)]
        res = CommandShow().execute(args)
        self.assertFalse(res)

        # test invalid input
        args = ['notifications', "blah"]
        res = CommandShow().execute(args)
        self.assertFalse(res)
示例#25
0
 def quit(self):
     print('Shutting down.  This may take a bit...')
     self.go_on = False
     Blockchain.Default().Dispose()
     reactor.stop()
     NodeLeader.Instance().Shutdown()
示例#26
0
    def ExecutionCompleted(self, engine, success, error=None):

        height = Blockchain.Default().Height + 1
        tx_hash = None

        if engine.ScriptContainer:
            tx_hash = engine.ScriptContainer.Hash

        if not tx_hash:
            tx_hash = UInt256(data=bytearray(32))

        entry_script = None
        try:
            # get the first script that was executed
            # this is usually the script that sets up the script to be executed
            entry_script = UInt160(data=engine.ExecutedScriptHashes[0])

            # ExecutedScriptHashes[1] will usually be the first contract executed
            if len(engine.ExecutedScriptHashes) > 1:
                entry_script = UInt160(data=engine.ExecutedScriptHashes[1])
        except Exception as e:
            logger.error("Could not get entry script: %s " % e)

        payload = []
        for item in engine.EvaluationStack.Items:
            payload_item = stack_item_to_py(item)
            payload.append(payload_item)

        if success:

            # dispatch all notify events, along with the success of the contract execution
            for notify_event_args in self.notifications:
                self.events_to_dispatch.append(
                    NotifyEvent(SmartContractEvent.RUNTIME_NOTIFY,
                                notify_event_args.State,
                                notify_event_args.ScriptHash, height, tx_hash,
                                success, engine.testMode))

            if engine.Trigger == Application:
                self.events_to_dispatch.append(
                    SmartContractEvent(SmartContractEvent.EXECUTION_SUCCESS,
                                       payload, entry_script, height, tx_hash,
                                       success, engine.testMode))
            else:
                self.events_to_dispatch.append(
                    SmartContractEvent(SmartContractEvent.VERIFICATION_SUCCESS,
                                       payload, entry_script, height, tx_hash,
                                       success, engine.testMode))

        else:
            if engine.Trigger == Application:
                self.events_to_dispatch.append(
                    SmartContractEvent(SmartContractEvent.EXECUTION_FAIL,
                                       [payload, error, engine._VMState],
                                       entry_script, height, tx_hash, success,
                                       engine.testMode))
            else:
                self.events_to_dispatch.append(
                    SmartContractEvent(SmartContractEvent.VERIFICATION_FAIL,
                                       [payload, error, engine._VMState],
                                       entry_script, height, tx_hash, success,
                                       engine.testMode))

        self.notifications = []
示例#27
0
    def json_rpc_method_handler(self, method, params):

        if method == "getaccountstate":
            acct = Blockchain.Default().GetAccountState(params[0])
            if acct is None:
                try:
                    acct = AccountState(
                        script_hash=Helper.AddrStrToScriptHash(params[0]))
                except Exception as e:
                    raise JsonRpcError(
                        -2146233033,
                        "One of the identified items was in an invalid format."
                    )

            return acct.ToJson()

        elif method == "getassetstate":
            asset_id = UInt256.ParseString(params[0])
            asset = Blockchain.Default().GetAssetState(asset_id.ToBytes())
            if asset:
                return asset.ToJson()
            raise JsonRpcError(-100, "Unknown asset")

        elif method == "getbestblockhash":
            return '0x%s' % Blockchain.Default().CurrentHeaderHash.decode(
                'utf-8')

        elif method == "getblock":
            # this should work for either str or int
            block = Blockchain.Default().GetBlock(params[0])
            if not block:
                raise JsonRpcError(-100, "Unknown block")
            return self.get_block_output(block, params)

        elif method == "getblockcount":
            return Blockchain.Default().Height + 1

        elif method == "getblockhash":
            height = params[0]
            if height >= 0 and height <= Blockchain.Default().Height:
                return '0x%s' % Blockchain.Default().GetBlockHash(
                    height).decode('utf-8')
            else:
                raise JsonRpcError(-100, "Invalid Height")

        elif method == "getblocksysfee":
            height = params[0]
            if height >= 0 and height <= Blockchain.Default().Height:
                return Blockchain.Default().GetSysFeeAmountByHeight(height)
            else:
                raise JsonRpcError(-100, "Invalid Height")

        elif method == "getconnectioncount":
            return len(NodeLeader.Instance().Peers)

        elif method == "getcontractstate":
            script_hash = UInt160.ParseString(params[0])
            contract = Blockchain.Default().GetContract(script_hash.ToBytes())
            if contract is None:
                raise JsonRpcError(-100, "Unknown contract")
            return contract.ToJson()

        elif method == "getrawmempool":
            return list(
                map(lambda hash: "0x%s" % hash.decode('utf-8'),
                    NodeLeader.Instance().MemPool.keys()))

        elif method == "getversion":
            return {
                "port": self.port,
                "nonce": NodeLeader.Instance().NodeId,
                "useragent": settings.VERSION_NAME
            }

        elif method == "getrawtransaction":
            tx_id = UInt256.ParseString(params[0])
            tx, height = Blockchain.Default().GetTransaction(tx_id)
            if not tx:
                raise JsonRpcError(-100, "Unknown Transaction")
            return self.get_tx_output(tx, height, params)

        elif method == "getstorage":
            script_hash = UInt160.ParseString(params[0])
            key = binascii.unhexlify(params[1].encode('utf-8'))
            storage_key = StorageKey(script_hash=script_hash, key=key)
            storage_item = Blockchain.Default().GetStorageItem(storage_key)
            if storage_item:
                return storage_item.Value.hex()
            return None

        elif method == "gettxout":
            hash = params[0].encode('utf-8')
            index = params[1]
            utxo = Blockchain.Default().GetUnspent(hash, index)
            if utxo:
                return utxo.ToJson(index)
            else:
                return None

        elif method == "invoke":
            shash = UInt160.ParseString(params[0])
            contract_parameters = [
                ContractParameter.FromJson(p) for p in params[1]
            ]
            sb = ScriptBuilder()
            sb.EmitAppCallWithJsonArgs(shash, contract_parameters)
            return self.get_invoke_result(sb.ToArray())

        elif method == "invokefunction":
            contract_parameters = []
            if len(params) > 2:
                contract_parameters = [
                    ContractParameter.FromJson(p).ToVM() for p in params[2]
                ]
            sb = ScriptBuilder()
            sb.EmitAppCallWithOperationAndArgs(UInt160.ParseString(params[0]),
                                               params[1], contract_parameters)
            return self.get_invoke_result(sb.ToArray())

        elif method == "invokescript":
            script = params[0].encode('utf-8')
            return self.get_invoke_result(script)

        elif method == "sendrawtransaction":
            tx_script = binascii.unhexlify(params[0].encode('utf-8'))
            transaction = Transaction.DeserializeFromBufer(tx_script)
            result = NodeLeader.Instance().Relay(transaction)
            return result

        elif method == "validateaddress":
            return self.validateaddress(params)

        elif method == "getpeers":
            return self.get_peers()

        elif method == "getbalance":
            if self.wallet:
                return self.get_balance(params)
            else:
                raise JsonRpcError(-400, "Access denied.")

        elif method == "getwalletheight":
            if self.wallet:
                return self.wallet.WalletHeight
            else:
                raise JsonRpcError(-400, "Access denied.")

        elif method == "listaddress":
            if self.wallet:
                return self.list_address()
            else:
                raise JsonRpcError(-400, "Access denied.")

        elif method == "getnewaddress":
            if self.wallet:
                keys = self.wallet.CreateKey()
                account = Account.get(
                    PublicKeyHash=keys.PublicKeyHash.ToBytes())
                return account.contract_set[0].Address.ToString()
            else:
                raise JsonRpcError(-400, "Access denied.")

        raise JsonRpcError.methodNotFound()
示例#28
0
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("-m",
                        "--mainnet",
                        action="store_true",
                        default=False,
                        help="use MainNet instead of the default TestNet")
    parser.add_argument("-c",
                        "--config",
                        action="store",
                        help="Use a specific config file")

    # Where to store stuff
    parser.add_argument("--datadir",
                        action="store",
                        help="Absolute path to use for database directories")

    parser.add_argument("-o", "--output", help="Where to save output file")

    parser.add_argument("-t",
                        "--totalblocks",
                        help="Total blocks to export",
                        type=int)

    args = parser.parse_args()

    if args.mainnet and args.config:
        print(
            "Cannot use both --config and --mainnet parameters, please use only one."
        )
        exit(1)

    # Setting the datadir must come before setting the network, else the wrong path is checked at net setup.
    if args.datadir:
        settings.set_data_dir(args.datadir)

    # Setup depending on command line arguments. By default, the testnet settings are already loaded.
    if args.config:
        settings.setup(args.config)
    elif args.mainnet:
        settings.setup_mainnet()

    if not args.output:
        raise Exception("Please specify an output path")

    file_path = args.output

    # Instantiate the blockchain and subscribe to notifications
    blockchain = LevelDBBlockchain(settings.chain_leveldb_path)
    Blockchain.RegisterBlockchain(blockchain)

    chain = Blockchain.Default()

    with open(file_path, 'wb') as file_out:

        total = Blockchain.Default().Height - 1

        if args.totalblocks:
            total = args.totalblocks

        total_block_output = total.to_bytes(4, 'little')

        print("Using network %s " % settings.net_name)
        print("Will export %s blocks to %s " % (total, file_path))

        file_out.write(total_block_output)

        for index in trange(total, desc='Exporting blocks:', unit=' Block'):

            block = chain.GetBlockByHeight(index)
            block.LoadTransactions()
            output = binascii.unhexlify(block.ToArray())
            output_length = len(output).to_bytes(4, 'little')
            file_out.write(output_length)
            file_out.write(output)

    print("Exported %s blocks to %s " % (total, file_path))
示例#29
0
    def __init__(self, path, passwordKey, create):

        self._path = path

        if create:
            self._iv = bytes(Random.get_random_bytes(16))
            self._master_key = bytes(Random.get_random_bytes(32))
            self._keys = {}
            self._contracts = {}
            self._coins = {}

            if Blockchain.Default() is None:
                self._indexedDB = LevelDBBlockchain(Settings.LEVELDB_PATH)
                Blockchain.RegisterBlockchain(self._indexedDB)
            else:
                self._indexedDB = Blockchain.Default()
            #self._node = RemoteNode(url=TEST_NODE)

            self._current_height = 0

            self.BuildDatabase()

            passwordHash = hashlib.sha256(passwordKey.encode('utf-8')).digest()
            master = AES.new(passwordHash, AES.MODE_CBC, self._iv)
            mk = master.encrypt(self._master_key)
            self.SaveStoredData('PasswordHash', passwordHash)
            self.SaveStoredData('IV', self._iv),
            self.SaveStoredData('MasterKey', mk)
            #        self.SaveStoredData('Version') { Version.Major, Version.Minor, Version.Build, Version.Revision }.Select(p => BitConverter.GetBytes(p)).SelectMany(p => p).ToArray());

            self.SaveStoredData('Height',
                                self._current_height.to_bytes(4, 'little'))

        else:
            self.BuildDatabase()

            passwordHash = self.LoadStoredData('PasswordHash')
            if passwordHash is None:
                raise Exception("Password hash not found in database")

            hkey = hashlib.sha256(passwordKey.encode('utf-8'))

            if passwordHash is not None and passwordHash != hashlib.sha256(
                    passwordKey.encode('utf-8')).digest():
                raise Exception("Incorrect Password")

            self._iv = self.LoadStoredData('IV')
            master_stored = self.LoadStoredData('MasterKey')
            aes = AES.new(hkey.digest(), AES.MODE_CBC, self._iv)
            self._master_key = aes.decrypt(master_stored)

            self._keys = self.LoadKeyPairs()
            self._contracts = self.LoadContracts()
            self._watch_only = self.LoadWatchOnly()
            self._coins = self.LoadCoins()
            try:
                h = int(self.LoadStoredData('Height'))
                self._current_height = h
            except Exception as e:
                print("couldnt load height data %s " % e)
                self._current_height = 0

#            self._current_height = 470000

            del passwordKey
示例#30
0
    def json_rpc_method_handler(self, method, params):

        if method == "getaccountstate":
            acct = Blockchain.Default().GetAccountState(params[0])
            if acct is None:
                try:
                    acct = AccountState(script_hash=Helper.AddrStrToScriptHash(params[0]))
                except Exception as e:
                    raise JsonRpcError(-2146233033, "One of the identified items was in an invalid format.")

            return acct.ToJson()

        elif method == "getassetstate":
            asset_id = UInt256.ParseString(params[0])
            asset = Blockchain.Default().GetAssetState(asset_id.ToBytes())
            if asset:
                return asset.ToJson()
            raise JsonRpcError(-100, "Unknown asset")

        elif method == "getbestblockhash":
            return '0x%s' % Blockchain.Default().CurrentHeaderHash.decode('utf-8')

        elif method == "getblock":
            # this should work for either str or int

            block = Blockchain.Default().GetBlock(params[0])
            if not block:
                raise JsonRpcError(-100, "Unknown block")
            return self.get_block_output(block, params)

        elif method == "getblockcount":
            return Blockchain.Default().Height + 1

        elif method == "getblockhash":
            height = params[0]
            if height >= 0 and height <= Blockchain.Default().Height:
                return '0x%s' % Blockchain.Default().GetBlockHash(height).decode('utf-8')
            else:
                raise JsonRpcError(-100, "Invalid Height")

        elif method == "getblocksysfee":
            height = params[0]
            if height >= 0 and height <= Blockchain.Default().Height:
                return Blockchain.Default().GetSysFeeAmountByHeight(height)
            else:
                raise JsonRpcError(-100, "Invalid Height")

        elif method == "getconnectioncount":
            return len(NodeLeader.Instance().Peers)

        elif method == "getcontractstate":
            script_hash = UInt160.ParseString(params[0])
            contract = Blockchain.Default().GetContract(script_hash.ToBytes())
            if contract is None:
                raise JsonRpcError(-100, "Unknown contract")
            return contract.ToJson()

        elif method == "getrawmempool":
            return list(map(lambda hash: "0x%s" % hash.decode('utf-8'), NodeLeader.Instance().MemPool.keys()))

        elif method == "getversion":
            return {
                "port": self.port,
                "nonce": NodeLeader.Instance().NodeId,
                "useragent": settings.VERSION_NAME
            }

        elif method == "getrawtransaction":
            tx_id = UInt256.ParseString(params[0])
            tx, height = Blockchain.Default().GetTransaction(tx_id)
            if not tx:
                raise JsonRpcError(-100, "Unknown Transaction")
            return self.get_tx_output(tx, height, params)

        elif method == "getstorage":
            script_hash = UInt160.ParseString(params[0])
            key = binascii.unhexlify(params[1].encode('utf-8'))
            storage_key = StorageKey(script_hash=script_hash, key=key)
            storage_item = Blockchain.Default().GetStorageItem(storage_key)
            if storage_item:
                return storage_item.Value.hex()
            return None

        elif method == "gettxout":
            hash = params[0].encode('utf-8')
            index = params[1]
            utxo = Blockchain.Default().GetUnspent(hash, index)
            if utxo:
                return utxo.ToJson(index)
            else:
                return None

        elif method == "invoke":
            shash = UInt160.ParseString(params[0])
            contract_parameters = [ContractParameter.FromJson(p) for p in params[1]]
            sb = ScriptBuilder()
            sb.EmitAppCallWithJsonArgs(shash, contract_parameters)
            return self.get_invoke_result(sb.ToArray())

        elif method == "invokefunction":
            contract_parameters = []
            if len(params) > 2:
                contract_parameters = [ContractParameter.FromJson(p).ToVM() for p in params[2]]
            sb = ScriptBuilder()
            sb.EmitAppCallWithOperationAndArgs(UInt160.ParseString(params[0]), params[1], contract_parameters)
            return self.get_invoke_result(sb.ToArray())

        elif method == "invokescript":
            script = params[0].encode('utf-8')
            return self.get_invoke_result(script)

        elif method == "sendrawtransaction":
            tx_script = binascii.unhexlify(params[0].encode('utf-8'))
            transaction = Transaction.DeserializeFromBufer(tx_script)
            result = NodeLeader.Instance().Relay(transaction)
            return result

        elif method == "mw_construct_send_tx":
            return MyWishMethods.construct_send_tx(self.wallet, params)

        elif method == "mw_construct_deploy_tx":
            return MyWishMethods.construct_deploy_tx(self.wallet, params)

        elif method == "mw_construct_invoke_tx":
            return MyWishMethods.construct_invoke_tx(self.wallet, params)

        elif method == "getapplicationlog":
            assert(all([x in '1234567890abcdefABCDEFxX' for x in params[0]])) # prevent traversal
            try:
                with open('/home/neo/neo-python/notis/' + params[0]) as f:
                    res =  [json.loads(x) for x in f.read().split('\n') if x]
                    return [{'name': x['notify_type'], 'contract': x['contract'], 'args': x['payload']} for x in res]
            except FileNotFoundError:
                return ([])

        elif method == "submitblock":
            raise NotImplementedError()

        elif method == "validateaddress":
            return self.validateaddress(params)

        elif method == "getpeers":
            return self.get_peers()

        raise JsonRpcError.methodNotFound()