09/11/2018, 23:59

Demo Blockchain với PHP

Như các bạn cũng đã biết hoặc nghe loáng thoáng ở đâu đó về BlockChain, Blockchain hiện nay đang là xu hướng mới, đi đến đâu cũng blockchain, và hầu hết 1 số hội thảo công nghệ thì chủ đề blockchain luôn được nhiều các bạn lập trình viên cũng như các nhà quản lý doanh nghiệp đều quan tâm đến, ở bài ...

Như các bạn cũng đã biết hoặc nghe loáng thoáng ở đâu đó về BlockChain, Blockchain hiện nay đang là xu hướng mới, đi đến đâu cũng blockchain, và hầu hết 1 số hội thảo công nghệ thì chủ đề blockchain luôn được nhiều các bạn lập trình viên cũng như các nhà quản lý doanh nghiệp đều quan tâm đến, ở bài viết này mình sẽ hướng dẫn các bạn viết 1 blockchain trong php.

Mình sẽ lướt qua khái niệm về blockchain theo cách mình hiểu 1 chút, để bạn nào chưa biết thì có thể hiểu qua về nó và bạn nào biết rồi thì cũng có thể đóng góp ý kiến của các bạn,

Vậy, đầu tiên blockchain là gì ? mà sao đi đâu cũng thấy nhắc đến blockchain? blockchain ra đời khi nào ? Blockchain dùng để làm gì? ứng dụng vào những cái việc gì? nghe thoáng qua ở đâu nói rằng blockchain là bitcoin, hô hố, có phải không nhỉ ?

Thưa các bạn, mình sẽ tóm tắt 1 vài dòng bên dưới về nó:

Blockchain (chuỗi khối), tên ban đầu block chain là một cơ sở dữ liệu phân cấp lưu trữ thông tin trong các khối thông tin được liên kết với nhau bằng mã hóa và mở rộng theo thời gian.Mỗi khối thông tin đều chứa thông tin về thời gian khởi tạo và được liên kết tới khối trước đó, kèm một mã thời gian và dữ liệu giao dịch.Blockchain được thiết kế để chống lại việc thay đổi của dữ liệu: Một khi dữ liệu đã được mạng lưới chấp nhận thì sẽ không có cách nào thay đổi được nó.

Blockchain được đảm bảo nhờ cách thiết kế sử dụng hệ thống tính toán phân cấp với khả năng chịu lỗi byzantine cao. Vì vậy sự đồng thuận phân cấp có thể đạt được nhờ Blockchain. Vì vậy Blockchain phù hợp để ghi lại những sự kiện, hồ sơ y tế, xử lý giao dịch, công chứng, danh tính và chứng minh nguồn gốc. Việc này có tiềm năng giúp xóa bỏ các hậu quả lớn khi dữ liệu bị thay đổi trong bối cảnh thương mại toàn cầu.

Blockchain đầu tiên được phát minh và thiết kế bới Satoshi Nakamoto vào năm 2008 và được hiện thực hóa vào năm sau đó như là một phần cốt lõi của Bitcoin.

Bạn tạo 1 thư mục blockchain trong thư mục webservice của bạn nhé, và tạo luôn 1 file index.php để chúng ta viết code trong đó nhé:

Ban đầu chúng ta sẽ khởi tạo 1 class có tên là Block, Class này sẽ làm nhiệm vụ mã hóa toàn bộ dữ liệu vào thành 1 chuỗi khóa, đoạn code sẽ như sau:

Class Block{
 
    public $index;
    public $previousHash;
    public $timeHash;
    public $data;
    public $hash;
 
    public function __construct($index = 0, $previousHash = ', $timeHash = ', $data = ')
    {
 
        $this->index = $index;
        $this->previousHash = $previousHash;
        $this->timeHash = $timeHash;
        $this->data = $data;
        $this->hash = $this->execHash();
    }
 
    public function execHash()
    {
         
        if(is_array($this->data))
        {
            $data_content = json_encode($this->data);
        }else{
            $data_content = $this->data;
        }
         
        return hash('sha256', $this->index.$this->previousHash.$this->timeHash.$data_content);
    }
 
}

mình giải thích qua về class này 1 chút để các bạn cùng hiểu nhé:

mình khởi tạo 5 biến ban đầu trong class, trong đó:

public $index; // biến này là index key của 1 block dữ liệu, ở ví dụ này của mình, mình sẽ dùng nó là index, nhưng nếu chúng ta áp dụng thực tế, thì chúng ta có thể coi nó như 1 khóa chính, 1 transaction id, để định danh cho 1 block dữ liệu
 
public $previousHash; // biến này này hash của block trước block này
 
public $timeHash; // biến này là thời gian mã hóa của block này
 
public $data; // biến này là data của block này
 
public $hash; // biến này chính là hash của block này

Tiếp theo là hàm __construct, như các bạn cũng đã biết, khi chúng ta sử dụng 1 class thì bao giờ hàm __construct trong class ( nếu có trong class ) nó sẽ được gọi vào đầu tiên sau đó nó sẽ gọi tiếp đến các hàm khác nếu có.

tại đây mình viết:

__construct($index = 0, $previousHash = ', $timeHash = ', $data = ')

Thì, lúc gọi nó sẽ là, ah mà thôi để lát sẽ nói phần gọi cái này sau, giờ ta đi tiếp đến hàm execHash(), hàm này chính là công việc tạo hash key cho 1 block, hiện mình đang sử dụng sha256

Okie, xong Class block

Chúng ta chuyển sang tạo Class Blockchain:

Class BlockChain extends Block{
 
    public $chain = array();
 
    public function __construct()
    {
 
    }
 
}

Class Blockchain này sẽ thực hiện các chức năng như tạo mới 1 block, check xem blockchain này có bị chỉnh sửa hay chưa ?

Như bên trên các bạn cũng thấy, mình khởi tạo 1 class có tên Blockchian và thừa kế lại class Block bên trên, trong class Blockchain này hiện chưa có gì ngoài biến $$hain đang được khai báo public và 1 hàm __construct(), việc tiếp theo chúng ta sẽ làm là tạo 1 hàm có chức năng khởi tạo block ban đầu, block ban đầu này cũng khá quan trọng, nó là 1 block ban đầu tạo ra hash, các block sau đó sẽ lấy hashkey của block này để thực hiện việc mã hóa của mình, vậy mình sẽ tạo hàm này trong class Blockchain

public function createGenesisBlock()
{
    return new Block(0,'hash_dau_tien', time(), 'data');
}

Tiếp theo chúng ta sẽ gọi hàm này trong hàm __construct để khi new Blockchain thì hàm createGenesisBlock sẽ được tự động gọi vào

Class BlockChain extends Block{
 
    public $chain = array();
 
    public function __construct()
    {
        $this->chain[] = $this->createGenesisBlock(); 
    }
}

Okie, tiếp theo chúng ta tạo 1 hàm có tên getLatestBlock, hàm này sẽ có nhiệm vụ get ra block cuối cùng trong blockchain, và hàm này có nội dung như sau:

private function getLatestBlock()
    {
        return $this->chain[(count($this->chain) - 1)];
    }

Hàm này thì đơn giản rồi nên mình sẽ không giải thích thêm về hàm này và đi vào viết 1 hàm tiếp theo, hàm này vô cùng quan trọng, hàm này sẽ giúp chúng ta thêm vào block những dữ liệu mới

public function addaBlock($index, $timeHash, $data)
    {
        $previousHash = $this->getLatestBlock()->hash;
        $this->chain[] = new Block($index, $previousHash, $timeHash, $data);
    }

Ở hàm này, mình phải lấy ra được hash của block trước, lấy nó để làm gì ạ? thưa rằng bạn nhìn dòng thứ 2 trong hàm này bạn sẽ thấy Class Block cần truyền vào 1 biến có tên previousHash, biến này khi thực hiện hash nó sẽ giống như 1 key trong hash, sau này cái previousHash nó cũng là 1 thành phần để nói rằng block này có hợp lệ không ? block này có bị chỉnh sửa không ?

Okie, có vẻ gần hoàn chỉnh rồi, chúng ra review lại class BlockChain 1 chút nhé

Class BlockChain extends Block{
 
    public $chain = array();
 
    public function __construct()
    {
        $this->chain[] = $this->createGenesisBlock(); 
    }
 
    public function createGenesisBlock()
    {
        return new Block(0,'hash_dau_tien', time(), 'data');
    }
 
    private function getLatestBlock()
    {
        return $this->chain[(count($this->chain) - 1)];
    }
 
    public function addaBlock($index, $timeHash, $data)
    {
        $previousHash = $this->getLatestBlock()->hash;
        $this->chain[] = new Block($index, $previousHash, $timeHash, $data);
    }
 
     
}

Tổng cả class Block bên trên chúng ta sẽ có

<?php
 
Class Block{
 
    public $index;
    public $previousHash;
    public $timeHash;
    public $data;
    public $hash;
 
    public function __construct($index = 0, $previousHash = ', $timeHash = ', $data = ')
    {
 
        $this->index = $index;
        $this->previousHash = $previousHash;
        $this->timeHash = $timeHash;
        $this->data = $data;
        $this->hash = $this->execHash();
    }
 
    public function execHash()
    {
         
        if(is_array($this->data))
        {
            $data_content = json_encode($this->data);
        }else{
            $data_content = $this->data;
        }
         
        return hash('sha256', $this->index.$this->previousHash.$this->timeHash.$data_content);
    }
 
}
 
Class BlockChain extends Block{
 
    public $chain = array();
 
    public function __construct()
    {
        $this->chain[] = $this->createGenesisBlock(); 
    }
 
    public function createGenesisBlock()
    {
        return new Block(0,'hash_dau_tien', time(), 'data');
    }
 
    private function getLatestBlock()
    {
        return $this->chain[(count($this->chain) - 1)];
    }
 
    public function addaBlock($index, $timeHash, $data)
    {
        $previousHash = $this->getLatestBlock()->hash;
        $this->chain[] = new Block($index, $previousHash, $timeHash, $data);
    }
 
}

Chúng ta sẽ thêm đoạn này vào cuối file index.php và chạy thử nó nhé

$bl = new BlockChain();
$bl->addaBlock(1,time(), 'Data thứ 2');
$bl->addaBlock(2,time(), 'Data thứ 3');
$bl->addaBlock(3,time(), 'Data thứ 4');

Sau khi chạy, chúng ta sẽ có kết quả như sau:

BlockChain Object
(
    [chain] => Array
        (
            [0] => Block Object
                (
                    [index] => 0
                    [previousHash] => ma_chuoi_dau_tien
                    [timeHash] => 1530436111
                    [data] => data cua toi can tao
                    [hash] => 1067948d9484bb8bf7dcf5a625db12521e8a4f395861dd93b0025aa7714417c6
                )
 
            [1] => Block Object
                (
                    [index] => 1
                    [previousHash] => 1067948d9484bb8bf7dcf5a625db12521e8a4f395861dd93b0025aa7714417c6
                    [timeHash] => 1530436111
                    [data] => Data thứ 2
                    [hash] => 3f4752159b07a36c2bef5feeda6f4eb25a0472e08d9f3ed629ff9b4293a1a776
                )
 
            [2] => Block Object
                (
                    [index] => 2
                    [previousHash] => 3f4752159b07a36c2bef5feeda6f4eb25a0472e08d9f3ed629ff9b4293a1a776
                    [timeHash] => 1530436111
                    [data] => Array
                        (
                            [transaction_id] => 12ewe1e12e12eqwd12e1
                            [content] => test
                        )
 
                    [hash] => be72872e39785b6ccaea102166d278e74ef10b9b7af066edead2a6107e6da27a
                )
 
            [3] => Block Object
                (
                    [index] => 3
                    [previousHash] => be72872e39785b6ccaea102166d278e74ef10b9b7af066edead2a6107e6da27a
                    [timeHash] => 1530436111
                    [data] => Data thứ 4
                    [hash] => 46af491628171e95276986c996e3f5c155642411bfefc7936fc4688e1d088f98
                )
 
        )
)

Như vậy là chúng ta đã tạo ra được blockchain với php, thật quá đơn giản phải không các bạn, ở bài sau mình sẽ hướng dẫn các bạn việc kiểm tra xem 1 trong các block trong blockchain đã bị chỉnh sửa hay chưa ?

Thêm phát kết là bitcoin chỉ là 1 loại tiền sử dụng công nghệ blockchain, chứ bitcoin không phải là blockchain, không thể lấy bitcoin làm tên gọi cho blockchain, các bạn đừng nhầm lẫn nhé, ai đang nhầm lẫn thì sửa lại luôn nhé. Hẹn gặp các bạn ở các bài tiếp theo

--toiit--

0