Exemplo n.º 1
0
 def create(self):
     print('ok')
     while True:
         try:
             # sleep for the remaining seconds of interval
             print('ok')
             with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as s:
                 s.connect(self.chainbase_address)
                 s.sendall(send_handler(MsgType.TYPE_TRANS_MAKE, b''))
                 *_, msgtype, content = recv_parser(s)
             print('content')
             print(content)
             if content == b'':
                 time.sleep(0.001)
                 pass
             else:
                 sha = hashlib.sha256()
                 sha.update(content[BLENGTH_TXID:])
                 print(content[:BLENGTH_TXID])
                 print('sha')
                 print(sha.digest())
                 # content = Transaction.unpack(content)
                 # content = trans_to_json(content)
                 # r = requests.post('http://127.0.0.1:23390/transaction_post', data=content)
                 # q = requests.post('http://127.0.0.1:23391/transaction_post', data=content)
                 # print(r.text)
                 # print(q.text)
                 time.sleep(0.01)
         except Exception as e:
             print('error')
             time.sleep(0.01)
         finally:
             pass
 def create(self):
     print('ok')
     while True:
         try:
             # sleep for the remaining seconds of interval
             print('ok')
             with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as s:
                 s.connect(self.chainbase_address)
                 s.sendall(send_handler(MsgType.TYPE_TRANS_MAKE, b''))
                 *_, msgtype, content = recv_parser(s)
             print('content')
             print(content)
             if content == b'':
                 time.sleep(0.1)
             else:
                 sha = hashlib.sha256()
                 sha.update(content[BLENGTH_TXID:])
                 print(content[:BLENGTH_TXID])
                 print('sha')
                 print(sha.digest())
                 time.sleep(0.01)
         except Exception as e:
             print('error')
             time.sleep(0.1)
         finally:
             pass
Exemplo n.º 3
0
def transaction():
    if request.method == 'GET':
        return r'<!DOCTYPE html><html><body><form action="/transaction" method=POST>' \
               r'To:<br><input type="text" name="to" value=""><br>Amount:<br><input ' \
               r'type="text" name="amount" value="" pattern="+[0-9]"><br>Private Key:<br><textarea rows="4" ' \
               r'cols="20" name="prikey" value=""></textarea><br>Input(TxID,index;):<br><textarea rows="4" cols="20" ' \
               r'name="input" value=""></textarea><br><input type="submit" value="Submit"></form> </body></html>'
    else:
        receiver = request.form['to']
        amount = int(request.form['amount'])
        prikey = request.form['prikey'].encode()
        ipt = request.form['input']

        ipt, index = ipt.split(',')

        ipt = unhexlify(ipt)
        index = int(index)

        prikey = prikey.replace(b'\r\n', b'\n')
        prikey = prikey.replace(b'\\n', b'\n')

        private_key = load_pem_private_key(prikey, None, default_backend())
        public_key = private_key.public_key()
        serialized_public = public_key.public_bytes(
            encoding=Encoding.PEM, format=PublicFormat.SubjectPublicKeyInfo)
        sha = hashlib.sha256()
        sha.update(serialized_public)
        public_key_hash = sha.digest()

        t_input = TransInput([(TXID(ipt), OUTPUT_INDEX(index))],
                             public_key_hash)
        t_output = TransOutput([(ASSET(amount),
                                 PUBLIC_KEY_HASH(unhexlify(receiver)))])
        trans = Transaction(t_input, t_output)
        trans.ready(private_key)
        result = trans_to_json(trans)

        fd = open('peer.txt', 'r')
        for line in fd.readlines():
            if line != '\n':
                print('http://' + line.rstrip() + '/transaction_post')
                r = requests.post('http://' + line.rstrip() +
                                  '/transaction_post',
                                  data=result)
                print(r.text)
        fd.close()

        with socket.socket(
                socket.AF_UNIX,
                socket.SOCK_STREAM) as s:  # submit the valid transaction

            s.connect(chainbase_address)
            s.sendall(send_handler(MsgType.TYPE_TRANS_WRITE, trans.b))
            *_, msgtype, content = recv_parser(s)
        if msgtype == MsgType.TYPE_RESPONSE_OK:
            return 'ok'
        else:
            print(trans.show_trans())
            return 'error'
    def handle(self):
        """
        handle messages from webchain and conchain
        :return: None
        """

        handlers = {
            # write the submitted transaction to the transpool
            MsgType.TYPE_TRANS_WRITE:
            self.processor_trans_write,

            # provide transactions in the transpool
            MsgType.TYPE_TRANS_READ:
            self.processor_trans_read,

            # write the submitted block (the result of consensus) to the blockchain
            # MsgType.TYPE_BLOCK_WRITE: self.processor_block_write,

            # convert the lightblock to normal block and write it to the blockchain
            # MsgType.TYPE_LIGHTBLOCK_WRITE: self.processor_lightblock_write,

            # search the transaction that has the given txid
            MsgType.TYPE_TRANS_SEARCH_TXID:
            self.processor_trans_search_txid,

            # return the previous hash for constructing nonce
            MsgType.TYPE_BLOCK_PREVIOUS_HASH:
            self.processor_prev_hash,

            # send back blocks whose indexes locate in [start, end]
            MsgType.TYPE_BLOCK_READ:
            self.processor_block_read,

            # create Trans
            MsgType.TYPE_TRANS_MAKE:
            self.processor_trans_make,

            # write macro_block_header in blockchain
            MsgType.TYPE_MACRO_BLOCK_HEADER_WRITE:
            self.processor_macro_block_header_write,

            # append macro_block_body to corresponding macro_block_header
            MsgType.TYPE_MACRO_BLOCK_BODY_WRITE:
            self.processor_macro_block_body_write,

            # write micro_block and append it to corresponding macro_block_header
            MsgType.TYPE_MICRO_BLOCK_WRITE:
            self.processor_micro_block_write,

            # get current parent blocks for pending block
            MsgType.TYPE_GET_PARENT_HASH:
            self.processor_get_parent_hash
        }

        *_, msgtype, content = recv_parser(self.request)

        handlers[msgtype](content)
    def test_004_previous_hash(self):
        with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as s:
            s.connect(self.address)
            s.sendall(send_handler(MsgType.TYPE_BLOCK_PREVIOUS_HASH, b''))
            header, length, msgtype, content = recv_parser(s)

            self.assertEqual(msgtype, MsgType.TYPE_RESPONSE_OK)
            self.assertEqual(len(content), 32)
            print(content)
Exemplo n.º 6
0
    def init_prev_hash(self):
        """get previous hash from chainbase when initializing"""
        with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as s:
            s.connect(self.chainbase_address)
            s.sendall(send_handler(MsgType.TYPE_BLOCK_PREVIOUS_HASH, b''))
            *_, msgtype, content = recv_parser(s)

            self.prev_hash = content
            print('prev_hash = ', content)
Exemplo n.º 7
0
    def handle(self):
        handlers = {
            MsgType.TYPE_NEW_BLOCK: self.server.on_new_block_received,
            MsgType.TYPE_BLOCK_READ: self.server.acquire_block,
            MsgType.TYPE_NODE_DISCOVER: self.server.peer.peer_discover
        }

        *_, msgtype, content = recv_parser(self.request)

        handlers[msgtype](content)
Exemplo n.º 8
0
    def add_block(self, block: Block) -> bool:
        """
        add the block to the chainbase
        :param block: binary block
        :return: True | False
        """
        with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as s:
            s.connect(self.chainbase_address)
            s.sendall(send_handler(MsgType.TYPE_BLOCK_WRITE, block.b))
            *_, msgtype, content = recv_parser(s)

        return msgtype == MsgType.TYPE_RESPONSE_OK
    def test_002_trans_read(self):

        with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as s:
            s.connect(self.address)
            s.sendall(send_handler(MsgType.TYPE_TRANS_READ, b''))
            header, length, msgtype, content = recv_parser(s)
            content = batch_parser(content)

            for i in content:
                Transaction.unpack(i)
            self.assertEqual(msgtype, MsgType.TYPE_RESPONSE_OK)
            self.assertEqual(len(content), 2)
Exemplo n.º 10
0
 def put_miner_use(self, usage, useful) -> List:
     with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as s:
         s.connect(self.chainbase_address)
         s.sendall(
             send_handler(
                 MsgType.TYPE_MINER_USE,
                 batch_handler(
                     [struct.pack('=d', usage),
                      struct.pack('=d', useful)])))
         *_, msgtype, content = recv_parser(s)
         result = batch_parser(content)
     return result
    def handle(self):
        handlers = {
            MsgType.TYPE_NEW_BLOCK: self.server.on_new_block_received,
            MsgType.TYPE_BLOCK_READ: self.server.acquire_block,
            MsgType.TYPE_NODE_DISCOVER: self.server.peer.peer_discover,
            MsgType.TYPE_NEW_LIGHTBLOCK:
            self.server.on_new_lightblock_received,
            MsgType.TYPE_MINER_CREDIT: self.server.get_miner_credit
        }

        *_, msgtype, content = recv_parser(self.request)

        handlers[msgtype](content)
Exemplo n.º 12
0
    def __get_trans(self) -> List[Transaction]:
        # self.chainbase_address
        with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as s:
            s.connect(self.chainbase_address)
            s.sendall(send_handler(MsgType.TYPE_TRANS_READ, b''))
            *_, msgtype, content = recv_parser(s)

            trans = []  # todo: the first transaction should reward the miner,
            # todo: the server may have a property named owner_address
            if msgtype == MsgType.TYPE_RESPONSE_OK:
                trans += batch_parser(content)

            return [Transaction.unpack(t) for t in trans]
 def get_parent_hash(self) -> list:
     """
     get pivot chain macro_block_header and tips in local DAG
     :return: a list of hash (the first hash refers to voting edge, others refer to reference edges)
     """
     with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as s:
         s.connect(self.chainbase_address)
         s.sendall(send_handler(MsgType.TYPE_GET_PARENT_HASH, None))
         *_, msgtype, content = recv_parser(s)
     result = list()
     len_ = int(len(content) / 32)
     for i in range(len_):
         result.append(content[i * 32:(i + 1) * 32])
     return result
    def handle(self):
        handlers = {
            MsgType.TYPE_NODE_DISCOVER: self.server.peer.peer_discover,
            MsgType.TYPE_NEW_MACRO_BLOCK_HEADER:
            self.server.on_new_macro_block_header_received,
            MsgType.TYPE_NEW_MACRO_BLOCK_BODY:
            self.server.on_new_macro_block_body_received,
            MsgType.TYPE_NEW_MICRO_BLOCK:
            self.server.on_new_micro_block_received
        }

        *_, msgtype, content = recv_parser(self.request)

        handlers[msgtype](content)
Exemplo n.º 15
0
def block():
    start = request.args.get('start', type=int)
    end = request.args.get('end', type=int)
    with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as s:
        s.connect(chainbase_address)
        s.sendall(
            send_handler(MsgType.TYPE_BLOCK_READ,
                         struct.pack('=i', start) + struct.pack('=i', end)))
        *_, msgtype, content = recv_parser(s)

        content = batch_parser(content)
        block = [Block.unpack(i).show_block() for i in content]

    return jsonify(block)
    def add_macro_block_body(self, macro_block_body: MacroBlockBody) -> bool:
        """
        add the macro_block_body to the chainbase
        :param macro_block_body: binary macro_block_body
        :return: True | False
        """
        with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as s:
            s.connect(self.chainbase_address)
            s.sendall(
                send_handler(MsgType.TYPE_MACRO_BLOCK_BODY_WRITE,
                             macro_block_body.b))
            *_, msgtype, content = recv_parser(s)

        return msgtype == MsgType.TYPE_RESPONSE_OK
    def add_macro_block_header(self,
                               macro_block_header: MacroBlockHeader) -> bool:
        """
        add the macro_block_header to the chainbase
        :param macro_block_header: binary macro_block_header
        :return: True | False
        """
        print('in add macro')
        with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as s:
            s.connect(self.chainbase_address)
            s.sendall(
                send_handler(MsgType.TYPE_MACRO_BLOCK_HEADER_WRITE,
                             macro_block_header.b))
            *_, msgtype, content = recv_parser(s)

        return msgtype == MsgType.TYPE_RESPONSE_OK
 def get_miner_credit(self, public_key_hash, num) -> List:
     with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as s:
         s.connect(self.chainbase_address)
         p = time.time() * 100000000
         print(struct.pack('=d', p))
         s.sendall(
             send_handler(
                 MsgType.TYPE_MINER_CREDIT,
                 batch_handler([
                     public_key_hash,
                     struct.pack('=d', num),
                     struct.pack('=d', p)
                 ])))
         *_, msgtype, content = recv_parser(s)
         result = batch_parser(content)
     return result
Exemplo n.º 19
0
def transaction_post():
    temp = str(request.get_data(), encoding='utf-8')
    trans = json_to_trans(temp)

    with socket.socket(
            socket.AF_UNIX,
            socket.SOCK_STREAM) as s:  # submit the valid transaction

        s.connect(chainbase_address)
        s.sendall(send_handler(MsgType.TYPE_TRANS_WRITE, trans.b))
        *_, msgtype, content = recv_parser(s)
        # print('end.....')
        # print(content)
    if msgtype == MsgType.TYPE_RESPONSE_OK:
        return 'ok'
    else:
        return 'error'
Exemplo n.º 20
0
    def handle(self):
        """
        handle messages from webchain and conchain
        :return: None
        """

        handlers = {
            # write the submitted transaction to the transpool
            MsgType.TYPE_TRANS_WRITE:
            self.processor_trans_write,

            # provide transactions in the transpool
            MsgType.TYPE_TRANS_READ:
            self.processor_trans_read,

            # write the submitted block (the result of consensus) to the blockchain
            MsgType.TYPE_BLOCK_WRITE:
            self.processor_block_write,

            # convert the lightblock to normal block and write it to the blockchain
            # MsgType.TYPE_LIGHTBLOCK_WRITE: self.processor_lightblock_write,

            # search the transaction that has the given txid
            MsgType.TYPE_TRANS_SEARCH_TXID:
            self.processor_trans_search_txid,

            # return the previous hash for constructing nonce
            MsgType.TYPE_BLOCK_PREVIOUS_HASH:
            self.processor_prev_hash,

            # send back blocks whose indexes locate in [start, end]
            MsgType.TYPE_BLOCK_READ:
            self.processor_block_read,

            # create Trans
            MsgType.TYPE_TRANS_MAKE:
            self.processor_trans_make

            # get miner's credit
            # MsgType.TYPE_MINER_CREDIT: self.processor_miner_credit,
        }

        *_, msgtype, content = recv_parser(self.request)

        handlers[msgtype](content)
Exemplo n.º 21
0
    def __get_trans(self) -> List[Transaction]:
        # self.chainbase_address
        with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as s:
            s.connect(self.chainbase_address)
            s.sendall(send_handler(MsgType.TYPE_TRANS_READ, b''))
            *_, msgtype, content = recv_parser(s)

            trans = []

            if msgtype == MsgType.TYPE_RESPONSE_OK:
                trans += batch_parser(content)

            private_key = ec.generate_private_key(ec.SECP256K1,
                                                  default_backend())
            public_key = private_key.public_key()
            public_key = public_key.public_bytes(
                Encoding.DER, PublicFormat.SubjectPublicKeyInfo)
            sha = hashlib.sha256()
            sha.update(public_key)
            public_key_hash = sha.digest()
            ipt = TransInput([(TXID(public_key_hash), OUTPUT_INDEX(0))],
                             public_key_hash)
            fd_ = open('ad1.txt', 'r')
            for index, line in enumerate(fd_.readlines()):
                if index == 0:
                    line = line.rstrip()
                    pr, pu = line.split('ENDDING')
                    temp = bytes(pu[2:-1], encoding='utf-8')
                    temp = temp.replace(b'\r\n', b'\n')
                    public_key = temp.replace(b'\\n', b'\n')
                    sha = hashlib.sha256()
                    sha.update(public_key)
                    public_key_hash = sha.digest()
                    break
            fd_.close()
            opt = TransOutput([(ASSET(20), public_key_hash)])
            tran = Transaction(ipt, opt, 0)
            tran.ready(private_key)
            trans.append(tran.b)
            # result = self.get_miner_credit(public_key_hash, 5)
            # print(result)
            print('len = ', len(trans))
            return [Transaction.unpack(t) for t in trans]
Exemplo n.º 22
0
    def __get_trans(self) -> List[Transaction]:

        with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as s:
            s.connect(self.chainbase_address)
            s.sendall(send_handler(MsgType.TYPE_TRANS_READ, b''))
            *_, msgtype, content = recv_parser(s)

            trans = []

            if msgtype == MsgType.TYPE_RESPONSE_OK:
                trans += batch_parser(content)

            private_key = ec.generate_private_key(ec.SECP256K1,
                                                  default_backend())
            public_key = private_key.public_key()
            public_key = public_key.public_bytes(
                Encoding.DER, PublicFormat.SubjectPublicKeyInfo)
            sha = hashlib.sha256()
            sha.update(public_key)
            public_key_hash = sha.digest()
            ipt = TransInput([(TXID(public_key_hash), OUTPUT_INDEX(0))],
                             public_key_hash)

            opt = TransOutput([(ASSET(20),
                                PUBLIC_KEY_HASH(miner_public_key_hash))])
            tran = Transaction(ipt, opt, 0)
            tran.ready(private_key)
            trans.append(tran.b)
            content = trans_to_json(tran)
            requests.post('http://127.0.0.1:23390/transaction_post',
                          data=content)
            if self.block_num < -50:
                self.get_miner_credit(miner_public_key_hash,
                                      0.5 / self.block_num)
            else:
                self.get_miner_credit(miner_public_key_hash, 0.5)
            # print(struct.unpack('=d', result[0]), struct.unpack('=d', result[1]))
            return [Transaction.unpack(t) for t in trans]
Exemplo n.º 23
0
    def handle(self):
        handlers = {}
        *_, msgtype, content = recv_parser(self.request)

        handlers[msgtype](content)
    def test_000_trans_write(self):
        """
        The first (genesis) block contains a transaction that pays 42 to the address that corresponds to the
        following private key. This test case first use this private key to issue and submit a transaction
        which pays 7 for 6 random addresses. This transaction is valid and stays in the pool of transactions.
        Then the test try to issue a new transaction. Because the 42 assets of the following private key were
        used up, the new transaction is invalid. Finally, the test pays 7 from random address 1 to address 2.
        """

        tinput = [(
            b'O\x1e,-\xe1\xa0!\x16D\x87\xcc\x923\xf7\xf6\xca\xad\xd1\t\x8eV\xdc\xe8t}N\xfa\x8af\xbe\xe7\xef',
            0)]

        private_key1 = load_pem_private_key(
            b'-----BEGIN PRIVATE KEY-----\nMIGEAgEAMBAGByqGSM49AgEGBSuBBAAKBG0w'
            b'awIBAQQg64DiDBUkuGC5rrTfH6uy\nHt6vhvHrMHj3Gm64SZtdqtKhRANCAATMIea'
            b'IK4vT0ni00F6GGW40qioinPFgXjsj\n6sZGivW9Ipj+zcDfPc7RxZuFeKFmbtVaUX'
            b'Z877DM4C8ELZs2DPVQ\n-----END PRIVATE KEY-----\n', None,
            default_backend())
        public_key = b'-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEzCHmiCuL09J4tNBehhluNKoqIpzx' \
                     b'YF47\nI+rGRor1vSKY/s3A3z3O0cWbhXihZm7VWlF2fO+wzOAvBC2bNgz1UA==\n-----END PUBLIC KEY-----\n'
        sha = hashlib.sha256()
        sha.update(public_key)
        public_key_hash = sha.digest()

        T1 = TransInput(tinput, public_key_hash)

        public_key_hash = []
        private_keys = []
        public_keys = []

        for i in range(6):
            private_key = ec.generate_private_key(ec.SECP256K1,
                                                  default_backend())
            private_keys.append(private_key)

            public_key = private_key.public_key()
            public_key = public_key.public_bytes(
                Encoding.PEM, PublicFormat.SubjectPublicKeyInfo)
            public_keys.append(public_key)

            sha = hashlib.sha256()
            sha.update(public_key)
            public_key_hash.append(sha.digest())

        toutput = [(7, public_key_hash[i]) for i in range(6)]
        T2 = TransOutput(toutput)

        T = Transaction(T1, T2)
        T.ready(private_key1)

        with socket.socket(
                socket.AF_UNIX,
                socket.SOCK_STREAM) as s:  # submit the valid transaction

            s.connect(self.address)
            payload = send_handler(MsgType.TYPE_TRANS_WRITE, T.b)
            s.sendall(payload)
            header, length, msgtype, content = recv_parser(s)

            self.assertEqual(content, b'')
            self.assertEqual(length, 0)
            self.assertEqual(
                msgtype, MsgType.TYPE_RESPONSE_OK)  # the chainbase returns OK

        with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as s:
            # submit the same transaction, but it is invalid this time

            s.connect(self.address)
            payload = send_handler(MsgType.TYPE_TRANS_WRITE, T.b)
            s.sendall(payload)
            header, length, msgtype, content = recv_parser(s)

            self.assertEqual(content, b'')
            self.assertEqual(length, 0)
            self.assertEqual(
                msgtype,
                MsgType.TYPE_RESPONSE_ERROR)  # the chainbase returns ERROR
        """
        construct a second valid transaction, which pay 7 from random address 1 to random address 2
        """
        private_key = private_keys[0]
        public_key = public_keys[0]
        public_key_hash1 = public_key_hash[0]

        T1 = TransInput([(T.txid, 0)], public_key_hash1)

        toutput = [(7, public_key_hash[1])]
        T2 = TransOutput(toutput)

        T = Transaction(T1, T2)
        T.ready(private_key)
        with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM
                           ) as s:  # submit the second valid transaction

            s.connect(self.address)
            payload = send_handler(MsgType.TYPE_TRANS_WRITE, T.b)
            s.sendall(payload)
            header, length, msgtype, content = recv_parser(s)

            self.assertEqual(content, b'')
            self.assertEqual(length, 0)
            self.assertEqual(
                msgtype, MsgType.TYPE_RESPONSE_OK)  # the chainbase returns OK
    def test_001_block_write(self):
        """
        use the same case as the test_000_trans_write, but transactions are seperated into different blocks
        :return:
        """
        # replace the following connection address with the address in the chainbase

        tinput = [(
            b'O\x1e,-\xe1\xa0!\x16D\x87\xcc\x923\xf7\xf6\xca\xad\xd1\t\x8eV\xdc\xe8t}N\xfa\x8af\xbe\xe7\xef',
            0)]

        private_key1 = load_pem_private_key(
            b'-----BEGIN PRIVATE KEY-----\nMIGEAgEAMBAGByqGSM49AgEGBSuBBAAKBG0w'
            b'awIBAQQg64DiDBUkuGC5rrTfH6uy\nHt6vhvHrMHj3Gm64SZtdqtKhRANCAATMIea'
            b'IK4vT0ni00F6GGW40qioinPFgXjsj\n6sZGivW9Ipj+zcDfPc7RxZuFeKFmbtVaUX'
            b'Z877DM4C8ELZs2DPVQ\n-----END PRIVATE KEY-----\n', None,
            default_backend())
        public_key = b'-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEzCHmiCuL09J4tNBehhluNKoqIpzx' \
                     b'YF47\nI+rGRor1vSKY/s3A3z3O0cWbhXihZm7VWlF2fO+wzOAvBC2bNgz1UA==\n-----END PUBLIC KEY-----\n'
        sha = hashlib.sha256()
        sha.update(public_key)
        public_key_hash = sha.digest()

        T1 = TransInput(tinput, public_key_hash)

        public_key_hash = []
        private_keys = []
        public_keys = []

        for i in range(6):
            private_key = ec.generate_private_key(ec.SECP256K1,
                                                  default_backend())
            private_keys.append(private_key)

            public_key = private_key.public_key()
            public_key = public_key.public_bytes(
                Encoding.PEM, PublicFormat.SubjectPublicKeyInfo)
            public_keys.append(public_key)

            sha = hashlib.sha256()
            sha.update(public_key)
            public_key_hash.append(sha.digest())

        toutput = [(7, public_key_hash[i]) for i in range(6)]
        T2 = TransOutput(toutput)

        T = Transaction(T1, T2)
        T.ready(private_key1)

        pri_key = private_keys[0]
        public_key_hash1 = public_key_hash[0]

        T8 = TransInput([(T.txid, 0)], public_key_hash1)

        toutput = [(7, public_key_hash[1])]
        T9 = TransOutput(toutput)

        T4 = Transaction(T8, T9)
        T4.ready(pri_key)

        at = Attachment()
        at.add_data(b'')
        at.ready()

        bd = BlockData([T, T4], at)
        t = time.time()
        block = Block(
            1, t, bd,
            b'G\xfdk\x88\xda5\xff\x8c\x97t\x9f\xcb\xe0\xa8\x07S\x8b9t:.9\x1d\xee\xf4\xb1\xda\xd1r\xaf\xfcu',
            33)
        """
        construct a second valid transaction, which pay 7 from random address 1 to random address 2 
        """

        with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM
                           ) as s:  # submit the second valid transaction

            s.connect(self.address)
            payload = send_handler(MsgType.TYPE_BLOCK_WRITE, block.b)
            s.sendall(payload)
            header, length, msgtype, content = recv_parser(s)

            self.assertEqual(content, b'')
            self.assertEqual(length, 0)
            self.assertEqual(
                msgtype, MsgType.TYPE_RESPONSE_OK)  # the chainbase returns OK