예제 #1
0
 async def sendRawTransaction(self, tx_data):
     evm_tx = rlp.decode(tx_data, EvmTransaction)
     tx = Transaction(code=Code.create_evm_code(evm_tx))
     success = await self.master.add_transaction(tx)
     if not success:
         return "0x" + bytes(32 + 4).hex()
     return id_encoder(tx.get_hash(), evm_tx.from_full_shard_id)
예제 #2
0
    async def sendTransaction(self, **data):
        def get_data_default(key, decoder, default=None):
            if key in data:
                return decoder(data[key])
            return default

        to = get_data_default("to", recipient_decoder, b"")
        startgas = get_data_default("gas", quantity_decoder, DEFAULT_STARTGAS)
        gasprice = get_data_default("gasPrice", quantity_decoder,
                                    DEFAULT_GASPRICE)
        gas_token_id = get_data_default("gasTokenId", quantity_decoder, 0)
        value = get_data_default("value", quantity_decoder, 0)
        transfer_token_id = get_data_default("transfer_token_id",
                                             quantity_decoder, 0)
        data_ = get_data_default("data", data_decoder, b"")
        v = get_data_default("v", quantity_decoder, 0)
        r = get_data_default("r", quantity_decoder, 0)
        s = get_data_default("s", quantity_decoder, 0)
        nonce = get_data_default("nonce", quantity_decoder, None)

        to_full_shard_id = get_data_default("toFullShardId",
                                            full_shard_id_decoder, None)
        from_full_shard_id = get_data_default("fromFullShardId",
                                              full_shard_id_decoder, None)
        network_id = get_data_default(
            "networkId", quantity_decoder,
            self.master.env.quark_chain_config.NETWORK_ID)

        if nonce is None:
            raise InvalidParams("Missing nonce")
        if not (v and r and s):
            raise InvalidParams("Missing v, r, s")
        if from_full_shard_id is None:
            raise InvalidParams("Missing fromFullShardId")

        if to_full_shard_id is None:
            to_full_shard_id = from_full_shard_id

        evm_tx = EvmTransaction(
            nonce,
            gasprice,
            startgas,
            gas_token_id,
            to,
            value,
            transfer_token_id,
            data_,
            v,
            r,
            s,
            from_full_shard_id=from_full_shard_id,
            to_full_shard_id=to_full_shard_id,
            network_id=network_id,
        )
        tx = Transaction(code=Code.create_evm_code(evm_tx))
        success = await self.master.add_transaction(tx)
        if not success:
            return None

        return id_encoder(tx.get_hash(), from_full_shard_id)
예제 #3
0
    def test_sendTransaction(self):
        id1 = Identity.create_random_identity()
        acc1 = Address.create_from_identity(id1, full_shard_key=0)
        acc2 = Address.create_random_account(full_shard_key=1)

        with ClusterContext(
            1, acc1, small_coinbase=True
        ) as clusters, jrpc_server_context(clusters[0].master):
            slaves = clusters[0].slave_list
            master = clusters[0].master

            is_root, block = call_async(master.get_next_block_to_mine(address=acc2))
            self.assertTrue(is_root)
            call_async(master.add_root_block(block))

            evm_tx = EvmTransaction(
                nonce=0,
                gasprice=6,
                startgas=30000,
                to=acc2.recipient,
                value=15,
                data=b"",
                from_full_shard_key=acc1.full_shard_key,
                to_full_shard_key=acc2.full_shard_key,
                network_id=slaves[0].env.quark_chain_config.NETWORK_ID,
                gas_token_id=master.env.quark_chain_config.genesis_token,
                transfer_token_id=master.env.quark_chain_config.genesis_token,
            )
            evm_tx.sign(id1.get_key())
            request = dict(
                to="0x" + acc2.recipient.hex(),
                gasPrice="0x6",
                gas=hex(30000),
                value="0xf",  # 15
                v=quantity_encoder(evm_tx.v),
                r=quantity_encoder(evm_tx.r),
                s=quantity_encoder(evm_tx.s),
                nonce="0x0",
                fromFullShardId="0x00000000",
                toFullShardId="0x00000001",
                network_id=hex(slaves[0].env.quark_chain_config.NETWORK_ID),
            )
            tx = Transaction(code=Code.create_evm_code(evm_tx))
            response = send_request("sendTransaction", [request])

            self.assertEqual(response, "0x" + tx.get_hash().hex() + "00000000")
            self.assertEqual(len(clusters[0].get_shard_state(2 | 0).tx_queue), 1)
            self.assertEqual(
                clusters[0].get_shard_state(2 | 0).tx_queue.pop_transaction(), evm_tx
            )
예제 #4
0
    async def donate(self, from_address, to_address, value=hex(10 ** 18)):
        """Faucet function to send value (default 1 token) from from_address to to_address.
        from_address must be one of the addresses in genesis_data/alloc.json.
        Only allow one pending tx at a time.
        Return tx id if success else None
        """
        if value > 100 * (10 ** 18):
            return None

        key = self.master.env.quark_chain_config.alloc_accounts.get(
            from_address.hex(), None
        )
        if not key:
            return None

        from_address = Address.deserialize(from_address)
        to_address = Address.deserialize(to_address)

        # Do nothing if there is already a pending tx
        result = await self.master.get_transactions_by_address(
            from_address, bytes(1), 1
        )
        if result:
            tx_list, next_token = result
            if tx_list:
                return None

        account_branch_data = await self.master.get_primary_account_data(from_address)
        nonce = account_branch_data.transaction_count
        network_id = self.master.env.quark_chain_config.NETWORK_ID
        evm_tx = EvmTransaction(
            nonce,
            10 ** 9,
            30000,
            to_address.recipient,
            value,
            b"",
            from_full_shard_id=from_address.full_shard_id,
            to_full_shard_id=to_address.full_shard_id,
            network_id=network_id,
        )
        evm_tx.sign(key)
        tx = Transaction(code=Code.create_evm_code(evm_tx))
        success = await self.master.add_transaction(tx)
        if not success:
            return None
        return id_encoder(tx.get_hash(), from_address.full_shard_id)
예제 #5
0
    def test_sendTransaction(self):
        id1 = Identity.create_random_identity()
        acc1 = Address.create_from_identity(id1, full_shard_id=0)
        acc2 = Address.create_random_account(full_shard_id=1)

        with ClusterContext(
                1, acc1, small_coinbase=True) as clusters, jrpc_server_context(
                    clusters[0].master):
            slaves = clusters[0].slave_list

            branch = Branch.create(2, 0)
            evm_tx = EvmTransaction(
                nonce=0,
                gasprice=6,
                startgas=30000,
                to=acc2.recipient,
                value=15,
                data=b"",
                from_full_shard_id=acc1.full_shard_id,
                to_full_shard_id=acc2.full_shard_id,
                network_id=slaves[0].env.quark_chain_config.NETWORK_ID,
            )
            evm_tx.sign(id1.get_key())
            request = dict(
                to="0x" + acc2.recipient.hex(),
                gasPrice="0x6",
                gas=hex(30000),
                value="0xf",  # 15
                v=quantity_encoder(evm_tx.v),
                r=quantity_encoder(evm_tx.r),
                s=quantity_encoder(evm_tx.s),
                nonce="0x0",
                fromFullShardId="0x00000000",
                toFullShardId="0x00000001",
                network_id=hex(slaves[0].env.quark_chain_config.NETWORK_ID),
            )
            tx = Transaction(code=Code.create_evm_code(evm_tx))
            response = send_request("sendTransaction", [request])

            self.assertEqual(response, "0x" + tx.get_hash().hex() + "00000000")
            self.assertEqual(len(slaves[0].shards[branch].state.tx_queue), 1)
            self.assertEqual(
                slaves[0].shards[branch].state.tx_queue.pop_transaction(),
                evm_tx)