示例#1
0
    def add_transaction(self,
                        sender_blockchain_address,
                        recipient_blockchain_address,
                        value,
                        sender_public_key=None,
                        signature=None):
        transaction = utils.sorted_dict_by_key({
            'sender_blockchain_address': sender_blockchain_address,
            'recipient_blockchain_address': recipient_blockchain_address,
            'value': float(value)
        })

        if sender_blockchain_address == MINING_SENDER:
            self.transaction_pool.append(transaction)
            return True

        if self.verify_transaction_signature(sender_public_key, signature,
                                             transaction):

            if (self.calculate_total_amount(sender_blockchain_address) <
                    float(value)):
                logger.error({
                    'action': 'add_transaction',
                    'error': 'no_value'
                })
                return False

            self.transaction_pool.append(transaction)
            return True
        return False
示例#2
0
 def valid_proof(self, transactions, previous_hash, nonce):
     guess_block = utils.sorted_dict_by_key({
         'transactions': transactions,
         'nonce': nonce,
         'previous_hash': previous_hash
     })
     guess_hash = self.hash(guess_block)
     return guess_hash[:self.difficulty] == '0'*self.difficulty
示例#3
0
    def add_transaction(self,
                        sender_blockchain_address,
                        recipient_blockchain_address,
                        value,
                        sender_public_key=None,
                        signature=None):
        """
        transactionを追加する.
        ex. wallet A -> wallet B に 1.0送金.

        Parameters
        ----------
        sender_blockchain_address: str
            wallet Aのblockchain address

        recipient_blockchain_address: str
            wallet Bのblockchain address

        value: float
            1.0

        sender_public_key: str

        signature : str

        Returns
        -------
        bool

        See Also
        --------
        """
        transaction = utils.sorted_dict_by_key({
            "sender_blockchain_address": sender_blockchain_address,
            "recipient_blockchain_address": recipient_blockchain_address,
            "value": float(value)
        })
        # miningの場合
        if sender_blockchain_address == MINING_SENDER:
            self.transaction_pool.append(transaction)
            return True

        # mining以外の場合
        if self.verify_transaction_signature(sender_public_key, signature,
                                             transaction):

            # 送り金がない場合
            if self.calculate_total_amount(sender_blockchain_address) < float(
                    value):
                logger.error({
                    'action': 'add_transaction',
                    'error': 'no_value'
                })
                return False

            self.transaction_pool.append(transaction)
            return True
        return False
 def add_transaction(self, sender_blockchain_address,
                     recipient_blockchain_address, value):
     transaction = utils.sorted_dict_by_key({
         'sender_blockchain_address': sender_blockchain_address,
         'recipient_blockchain_address': recipient_blockchain_address,
         'value': float(value)
     })
     self.transaction_pool.append(transaction)
     return True
示例#5
0
 def valid_proof(self, transactions, previous_hash, nonce,
                 dificulty=MINING_DIFFICULTY):
     guess_block = utils.sorted_dict_by_key({
         'transactions': transactions,
         'nonce': nonce,
         'previous_hash': previous_hash
     })
     guess_hash = self.hash(guess_block)
     return guess_hash[:dificulty] == '0'*dificulty
示例#6
0
 def create_block(self, nonce, previous_hash):
     block = utils.sorted_dict_by_key({
         'timestamp': time.time(),
         'transactions': self.transaction_pool,
         'nonce': nonce,
         'previous_hash': previous_hash
     })
     self.chain.append(block)
     self.transaction_pool = []
     return block
示例#7
0
 def create_genesis_block(self):
     print('create_genesis_block is called')
     block = utils.sorted_dict_by_key({
         'timestamp': time.time(),
         'transactions' : self.transaction_pool,
         'nonce': 0,
         'previous_hash': self.hash({})
     })
     self.chain.append(block)
     self.transaction_pool = []
示例#8
0
 def create_block(self, nonce, previous_hash):
     block = utils.sorted_dict_by_key({
         'timestamp': time.time(),
         'transactions': self.transaction_pool,
         'nonce': nonce,
         'previous_hash': previous_hash
     })
     self.chain.append(block)
     self.transaction_pool = []
     for node in self.neighbours:
         requests.delete(f'http://{node}/transactions')
     return block
示例#9
0
 def valid_proof(self, transactions, previous_hash, nonce,
                 difficulty=MINING_DIFFICULTY):
     # ブロックをつくって
     guess_block = utils.sorted_dict_by_key({
         'transactions': transactions,
         'previous_hash': previous_hash,
         'nonce': nonce
     })
     # ハッシュを作って
     guess_hash = self.hash(guess_block)
     # 判定をする
     return guess_hash[:difficulty] == '0'*difficulty
示例#10
0
	def generate_signature(self):
		sha256 = hashlib.sha256()
		transactions = utils.sorted_dict_by_key({
			'sender_blockchain_address': self.sender_blockchain_address,
			'recipient_blockchain_address': self.recipient_blockchain_address,
			'value': float(self.value)
		})
		sha256.update(str(transactions).encode('utf-8'))
		message = sha256.digest()
		private_key = SigningKey.from_string(
			bytes().fromhex(self.sender_private_key), curve=NIST256p)
		private_key_sign = private_key.sign(message)
		signature = private_key_sign.hex()
		return signature
示例#11
0
 def verify_transaction_signature(self, transaction, sender_public_key,
                                  signature):
     sha256 = hashlib.sha256()
     sha256.update(
         str(utils.sorted_dict_by_key(transaction)).encode('utf-8'))
     message = sha256.digest()
     verifying_key = VerifyingKey.from_string(
         bytes().fromhex(sender_public_key), curve=NIST256p)
     signature_bytes = bytes().fromhex(signature)
     try:
         verified_key = verifying_key.verify(signature_bytes, message)
         # return verified_key
         return True
     except BadSignatureError:
         return False
示例#12
0
    def valid_proof(self, transactions, prev_hash, nonce, difficulty=MINING_DIFICALITY):
        """
        nonceの計算を行う
        """
        # ハッシュ値の計算を行うブロックを定義しておく
        guess_block = utils.sorted_dict_by_key({
            'transactions': transactions,
            'nonce': nonce,
            'previous_hash': prev_hash,
        })

        # ハッシュ値の計算を行う
        guess_hash = self.hash(guess_block)

        # マイニングディフィカリティに応じたルールで判断する
        return guess_hash[:difficulty] == '0' * difficulty
示例#13
0
    def add_transaction(self, sender_blockchain_address, recipient_blockchain_address, value):
        """
        新しいトランザクションを作成し、トランザクションプールに追加する
        valueは金額を扱うので、floatでキャストする
        """
        # トランザクションを作成
        transaction = utils.sorted_dict_by_key({
            'sender_blockchain_address': sender_blockchain_address,
            'recipient_blockchain_address': recipient_blockchain_address,
            'value': float(value),
        })

        # トランザクションプールに追加する
        self.transaction_pool.append(transaction)
        # 追加に成功したらTrue
        return True
示例#14
0
    def create_block(self, nonce, previous_hash):
        print('create_block is called')
        block = utils.sorted_dict_by_key({
            'timestamp': time.time(),
            'difficulty': self.difficulty,
            'transactions': self.transaction_pool,
            'nonce': nonce,
            'previous_hash': previous_hash
        })

        if not self.valid_proof(block['transactions'],block['previous_hash'], 
                block['nonce'],block['difficulty']):
            return False, None

        self.chain.append(block)
        self.transaction_pool = []

        return True, block
示例#15
0
    def create_block(self, nonce, previous_hash):
        """
        Blockを作成する

        Parameters
        ----------
        nonce: int

        previous_hash: str

        Returns
        -------
        block : dict

        See Also
        --------
        >>> block_chain = BlockChain()
        >>> block_1 = block_chain.create_block(5, "hash 1")
        >>> block_1['nonce']
        5
        >>> block_1['previous_hash']
        'hash 1'
        >>> block_2 = block_chain.create_block(2, "hash 2")
        >>> block_2['nonce']
        2
        >>> block_2['previous_hash']
        'hash 2'
        """
        block = utils.sorted_dict_by_key({
            "timestamp": time.time(),
            "transactions": self.transaction_pool,
            "nonce": nonce,
            "previous_hash": previous_hash
        })
        self.chain.append(block)
        self.transaction_pool = []

        # 同期させる
        for node in self.neighbours:
            requests.delete(f"http://{node}/transactions")

        return block
示例#16
0
    def generate_signature(self):
        """
        署名を生成する
        ex. wallet A -> wallet B に 1.0送金.
        sender_blockchain_address: wallet Aのblockchain_address
        recipient_blockchain_address: wallet Bのblockchain_address
        value: 1.0

        秘密鍵とtransactionsからsignatureを生成する
        1. transactionsをSHA-256でハッシュ化(bytes)
        2. message: ハッシュ化したtransactionsを16進数文字列化
        3. NIST256pでprivate_keyを作成(bytes)

        See Also
        --------
        >>> wallet_A = Wallet()
        >>> wallet_B = Wallet()
        >>> t = Transaction(wallet_A.private_key, wallet_A.public_key, wallet_A.blockchain_address, wallet_B.blockchain_address, 1.0)
        >>> _ = t.generate_signature()
        """
        sha256 = hashlib.sha256()
        transaction = utils.sorted_dict_by_key({
            "sender_blockchain_address":
            self.sender_blockchain_address,
            "recipient_blockchain_address":
            self.recipient_blockchain_address,
            "value":
            float(self.value)
        })
        # sha256のupdate
        sha256.update(str(transaction).encode("utf-8"))
        # hashのメッセージ
        message = sha256.digest()
        # private_keyの作成
        private_key = SigningKey.from_string(bytes().fromhex(
            self.sender_private_key),
                                             curve=NIST256p)
        # signアルゴリズム
        private_key_sign = private_key.sign(message)
        signature = private_key_sign.hex()
        return signature
示例#17
0
 def generate_signature(self):
     """ 送金者の秘密鍵でトランザクションに署名
     トランザクションをsha256でハッシュ化
     PrivateKey.sign(message_hash)でSignatureオブジェクトを作成
     署名結果のrとsをタプルで返す
     """
     sha256 = hashlib.sha256()
     transaction = utils.sorted_dict_by_key({
         'sender_blockchain_address': self.sender_blockchain_address,
         'recipient_blockchain_address': self.recipient_blockchain_address,
         'value': float(self.value)
     })
     sha256.update(str(transaction).encode('utf-8'))
     message = sha256.digest()
     msg_hex = message.hex()
     msg_hex_str = str(msg_hex)
     msg_hex_str_0x = '0x' + msg_hex_str
     priv_int = int('0x'+self.sender_private_key, 0)
     priv = PrivateKey(priv_int)
     sig = priv.sign(int(msg_hex_str_0x, 0))
     return (sig.r, sig.s)
示例#18
0
    def add_transaction(self, sender_blockchain_address,
                        recipient_blockchain_address, value,
                        sender_public_key=None, signature=None):
        # valueは小数点がくるためfloat
        transaction = utils.sorted_dict_by_key({
            'sender_blockchain_address': sender_blockchain_address,
            'recipient_blockchain_address': recipient_blockchain_address,
            'value': float(value)
        })

        # マイニング処理の場合
        if sender_blockchain_address == MINING_SENDER:
            self.transaction_pool.append(transaction)
            return True

        # signatureをチェック
        if self.verify_transaction_signature(
                sender_public_key, signature, transaction):
            self.transaction_pool.append(transaction)
            return True
        return False
示例#19
0
    def valid_proof(self,
                    transactions,
                    previous_hash,
                    nonce,
                    difficulty=MINING_DIFFICULTY):
        """
        nonceを計算する.

        Parameters
        ----------
        transactions: list of dicts
            [{"recipient_blockchain_address": str, "sender_blockchain_address": str, "value": float}]

        previous_hash: str
            hash化([{"nonce": int, "previous_hash": str, "timestamp": float, "transactions": list}])

        nonce: int
            サーチ対象

        difficulty: int
            miningの難易度.hash化した文字列の先頭"0"の連続数

        Returns
        -------
        bool

        See Also
        --------
        """
        guess_block = utils.sorted_dict_by_key({
            "transactions": transactions,
            "nonce": nonce,
            "previous_hash": previous_hash
        })
        guess_hash = self.hash(guess_block)
        return guess_hash[:difficulty] == "0" * difficulty
示例#20
0
    def create_block(self, nonce, previous_hash):
        """ブロックチェーンを作成する関数

        作成したブロックをブロックチェーンのリストに追加し、
        トランザクションプールを空にする
        """
        # ブロックを作成
        block = {
            'timestamp': time.time(),
            'transactions': self.transaction_pool,
            'nonce': nonce,
            'previous_hash': previous_hash,
        }

        # ブロックをソートする ハッシュ化したときに毎回同じハッシュ値になるように
        sorted_block = utils.sorted_dict_by_key(block)

        # ブロックを追加
        self.chain.append(sorted_block)

        # トランザクションプールを空にする
        self.transaction_pool = []

        return sorted_block
示例#21
0
    def __handle_message(self, msg, is_core, peer=None):
        """
            ConnectionManagerに引き渡すコールバックの中身。
        """
        print('message_type : ', msg[2])
        if peer is not None:
            if msg[2] == MSG_REQUEST_FULL_CHAIN:
                # walletのチェーンを同期
                print('Send our latest blockchain for reply to : ', peer)
                my_chain = self.blockchain.chain
                chain_data = json.dumps(my_chain)
                new_message = self.cm.get_message_text(RSP_FULL_CHAIN,
                                                       chain_data)
                self.cm.send_msg(peer, new_message)
            elif msg[2] == MSG_REQUEST_KEY_INFO:
                # walletにminerの鍵情報を渡す
                key_info = pickle.dumps(self.miners_wallet, 0).decode()
                m_type = MSG_KEY_INFO
                message = self.cm.get_message_text(m_type, key_info)
                self.cm.send_msg(peer, message)
            elif msg[2] == MSG_DELETE_TRANSACTION:
                # transaction poolを空に
                print('DELETE_TRANSACTION is called')
                self.blockchain.transaction_pool = []
        else:
            if msg[2] == MSG_NEW_TRANSACTION:
                print('NEW_TRANSACTION command is called')
                payload = json.loads(msg[4])
                new_transaction = utils.sorted_dict_by_key({
                    'sender_blockchain_address':
                    payload['sender_blockchain_address'],
                    'recipient_blockchain_address':
                    payload['recipient_blockchain_address'],
                    'value':
                    float(payload['value'])
                })
                current_transactions = self.blockchain.transaction_pool.copy()
                print('new transaction : ', new_transaction)
                if new_transaction in current_transactions:
                    print('transaction is already in pool')
                    return
                else:
                    signature = pickle.loads(
                        payload['signature'].encode('utf8'))
                    print('signature', signature)
                    is_transacted = self.blockchain.add_transaction(
                        payload['sender_blockchain_address'],
                        payload['recipient_blockchain_address'],
                        payload['value'], payload['sender_public_key'],
                        signature)
                    if is_transacted:
                        print('new transaction is generated')
                        print('\n\ntransaction_pool',
                              self.blockchain.transaction_pool)
                    if not is_core:
                        # ウォレットからのトランザクションはブロードキャスト
                        print('transaction bloadcasted')
                        m_type = MSG_NEW_TRANSACTION
                        new_message = self.cm.get_message_text(m_type, msg[4])
                        self.cm.send_msg_to_all_peer(new_message)
            elif msg[2] == RSP_FULL_CHAIN:
                print('RSP_FULL_CHAIN command is called')
                if not is_core:
                    return

                new_block_chain = json.loads(msg[4])
                self.blockchain.resolve_conflicts(new_block_chain)