Làm thế nào để tự viết và deploy Smart Contract?
I. Smart Contract là gì?
Smart contract là một giao thức máy tính, được dùng để số hoá những việc như xác nhận, thực hiện sự thoả thuận hoặc việc thi hành hợp đồng. Các Smart Contract có khả năng thực hiện các giao dịch mà không cần bên trung gian thứ ba. Những giao dịch này có thể dễ dàng được theo dõi và không thể bị thay đổi.
Những người ủng hộ cho rằng có rất nhiều điều khoản hợp đồng có thể áp dụng Smart Contract vào một phần hay toàn bộ để chúng có thể được thực hiện một cách bán tự động hay hoàn toàn tự động. Mục tiêu của Smart Contract là cung cấp được sự an toàn tốt hơn và giảm thiểu những chi phí giao dịch phát sinh hơn so với các loại hợp đồng truyền thống.
Có nhiều loại tiền điện tử có thể được dùng để phát triển các Smart Contract. Ở đây chúng ta sẽ sử dụng loại tiền ảo có tên là Ethereum.
II. Ethererum platform
Trước khi đi vào phần chính là viết 1 Smart Contract. Chúng ta cần hiểu được cách Ethereum platform thực thi Smart Contract như thế nào. Để hiểu rõ được điều này ta sẽ bắt đầu từ phần thấp nhất đó chính là môi trường để thực thi được Smart Contract.
1. Ethereum Virtual Machine (EVM)
Ethereum dùng EVM - một loại máy ảo đặc biệt để biên dịch code assembly. Việc bắt lập trình viên phải code ngôn ngữ assembly thì nghe có vẻ không được tiện dụng lắm. Nên chúng ta còn sẽ cần một ngôn ngữ lập trình để viết code cho Smart Contract.
2. Solidity
Solidity là một trong những ngôn ngữ chuyên dụng để viết Smart Contract. Mục đích chính của Solidity là giúp lập trình viên giải quyết vấn đề đề bất tiện ở trên. Không cần phải trực tiếp viết ra code assembly nhưng vẫn có thể thể tương tác được với EVM. Solidity là một ngôn ngữ hướng đối tượng, cú pháp còn phần tương tự JavaScript, C++, Python nên những lập trình viên đã có kinh nghiệm về những ngôn ngữ đó có thể học là sử dụng được ngôn ngữ Solidity một cách khá dễ dàng.
Trong mạng Ethereum, mỗi Smart Contract sẽ được thực thi bởi một miner và kết quả là một block sẽ được thêm vào mạng Ethereum đó. Miner tốn công thực hiện việc đó vậy nên nó xứng đáng được thưởng đúng không nào? Do vậy khi thực thi bất kì Smart Contract nào trên EVM thì đều tiêu tốn 1 lượng tiền ảo nhất định được gọi là gas. Phần tiền ảo đó dùng để thưởng cho miner. Smart Contract càng phức tạp thì lượng gas yêu cầu càng cao.
II. Case study sử dụng Smart Contract
Khi đã hiểu được 1 số khái niệm cơ bản. Giờ là lúc để chúng ta bắt đầu vào phần chính. Dưới đây ta sẽ xét 1 trường hợp cụ thể và dùng Smart Contract để giải quyết bài toán đó. Đương nhiên trên thực tế, Smart Contract không chỉ dùng để giải quyết mỗi trường hợp này mà sẽ còn rất nhiều trường hợp khác nữa. Sau khi đọc xong bài viết này, bạn có thể để trí tưởng tượng của mình bay xa và ứng dụng Smart Contract trong vô vàng tình huống khác!
1. Blockchain marketplace
Ta có 1 blockchain marketplace - 1 hệ thống chứa nhiều Smart Contract để phục vụ cho việc thoả thuận giữa những người chủ và những người cần tìm việc. Alice là người chủ. Trước sân nhà của cô ấy có rất nhiều cỏ nên đã tìm đến blockchain marketplace để tìm người dọn cỏ với mức giá thấp nhất có thể. Trong khi đó Bob là người tìm đến blockchain marketplace với vai trò là người cần tìm việc gì đó để kiếm tiền.
2. Alice và Bob được lợi khi thoả thuận với nhau bằng Smart Contract?
- Smart Contract căn cứ vào các điều khoản và thực hiện 1 cách tự động các đều khoản đó.
- Các điều khoản của Smart Contract được công bố minh bạch. Tất cả mọi người trên blockchain đều có thể thấy nội dung các điều khoản đó.
- Alice và Bob không thể tự ý thay đổi điều khoản của Smart Contract nên họ hoàn toàn có thể tin tưởng nhau.
- Chi phí để thực hiện transaction rất thấp so với các hệ thống thanh toán truyền thống.
III. Hướng dẫn viết Smart Contract giải quyết bài toán bên trên
Với bài toán trong case study bên trên. Ta chia phần nghiệp vụ thành 6 bước như hình bên dưới.
1. Giới thiệu vai trò của Alice và Bob trong Smart Contract
Sau khi phân tích nghiệp vụ, chúng ta sẽ viết 1 Smart Contract có tên gọi là OddjobPayContract, trong Smart Contract này ta có:
- Client: chính là Alice - người chủ có việc cần thuê.
- Tasker: chính là Bob - người cần làm việc để kiếm tiền.
- PayAmount: là lượng tiền ảo mà Alice sẽ phải trả cho Bob khi Bob dọn xong cỏ ở sân nhà của Alice.
pragma solidity ^0.4.4;
contract OddjobPayContract {
address public client;
address public tasker;
uint256 public payAmount;
constructor (address _client, address _tasker) public {
client = _client;
tasker = _tasker;
payAmount = 0;
}
}
2. Cho phép Client có thể chuyển tiền ảo cho Tasker
Tiếp theo chúng ta bổ sung phương thức payable để Alice có thể chuyển tiền ảo cho Smart Contract.
pragma solidity ^0.4.4;
contract OddjobPayContract {
address public client;
address public tasker;
uint256 public payAmount;
constructor (address _client, address _tasker) public {
client = _client;
tasker = _tasker;
payAmount = 0;
}
function () public payable {
require(client == msg.sender);
payAmount += msg.value;
}
}
3. Cho phép Smart Contract có thể chuyển tiền cho Tasker (Bob)
Tương tự, ta viết thêm phương thức sendPayAmountToTasker để cho phép Smart Contract có thể chuyển tiền ảo cho Bob khi anh ấy làm xong việc.
pragma solidity ^0.4.4;
contract OddjobPayContract {
address public deployer;
address public client;
address public tasker;
uint256 public payAmount;
constructor (address _client, address _tasker) public {
deployer = msg.sender;
client = _client;
tasker = _tasker;
payAmount = 0;
}
function () public payable {
require(client == msg.sender);
payAmount += msg.value;
}
function sendPayAmountToTasker() public {
require(deployer == msg.sender);
// transfer pay amount to tasker
tasker.transfer(payAmount);
// nullify pay amount manually
payAmount = 0;
}
}
IV. Deploy Smart Contract
Vậy là chúng ta đã viết xong Smart Contract! Công đoạn tiếp theo là deploy nó lên Ethereum blockchain để dùng.
1. Ganache
Chúng ta có thể sử dụng 1 mạng public blockchain hoặc một mạng blockchain cá nhân. Để phục vụ cho mục đích có sẵn 1 mạng blockchain 1 cách nhanh chóng và dễ dàng sử dụng cho mục đích deploy để test thực Smart Contract như thế này thì Ganache là 1 sự lựa chọn lý tưởng.
Ganache là 1 blockchain cá nhân dùng cho mục đích test và phát triển trên nền tảng Ethereum. Chỉ cần download Ganache về và double click để cài là bạn chúng ta đã có sẵn 1 blockchain với mặc định 10 tài khoản, mỗi tài có 100 ETH (đương nhiên chúng chỉ dùng được trong nội bộ). Minner cũng đã sẵn có. Ngoài ra còn rất nhiều thứ khác để được thiết lập sẵn.
Trong blockchain cá nhân mà Ganache đã thiết lập sẵn, chúng ta cần hiểu 1 số khái niệm sau:
- Account: ở đây ta cần tối thiểu 1 account cho Alice, 1 account cho Bob và 1 account dùng để deploy contract. Mỗi account sẽ có 1 address tương ứng.
- Balance: balance của 1 account là lượng tiền ảo mà account đó sở hữu ở thời điểm hiện tại. Mặc định Ganache thiết lập 1 account sở hữu 100 ETH.
- Minner: đóng vai trò thực hiện transaction.
2. Truffle
Trufle là 1 framework giúp chúng ta compile và deploy Smart Contract. Truffle có thể dễ dàng được cài đặt thông qua npm.
npm install -g truffle
3. Dùng Javascipt để viết phần code deploy
Như vậy chúng ta đã viết xong Smart Contract, chuẩn bị xong môi trường. Thứ còn thiếu duy nhất đó chính là phần code để mô tả deploy như thế nào. Phần code này ta sẽ chỉ định blockchain mà ta sử dụng là blockchain nào, sử dụng những account nào trong blockchain đó. Ở đây ta sử dụng Ganache nên ta sẽ trỏ đến RPC Server mà Ganache đang dùng.
const Web3 = require('web3')
const contract = require('truffle-contract')
const SmartContract = contract(require('./build/contracts/OddjobPayContract'))
const deployer = '0x11A533F09D7AFea2A333FE6E0Ff558a937c7D186'
const client = '0x92b0Ec8AAb0c69EE8500aaf471237d27fF7dF053'
const tasker = '0x11eF75EFDE91353d89065981ff88908133Fae1D5'
const web3Provider = new Web3.providers.HttpProvider(
'HTTP://127.0.0.1:7545' // address of RPC server
)
const web3 = new Web3(web3Provider)
web3.eth.getAccounts(error => {
if (error) {
throw new Error(`
Error while fetching accounts from RPC!
Check RPC address! The problem may be there!
`)
}
})
const fetchBalanceByAddress = async address => {
return new Promise(resolve => {
web3.eth.getBalance(address, (_, balance) => {
resolve(web3.fromWei(balance, 'ether').toString())
})
})
}
const printBalancesToConsole = async () => {
const deployerBalance = await fetchBalanceByAddress(deployer)
const clientBalance = await fetchBalanceByAddress(client)
const taskerBalance = await fetchBalanceByAddress(tasker)
console.log(`Deployer: ${deployerBalance}; Client: ${clientBalance}; Tasker: ${taskerBalance}`)
}
const run = async () => {
await printBalancesToConsole()
SmartContract.setProvider(web3Provider)
const smartContract = await SmartContract.new(
client, tasker, { gas: 1000000, from: deployer }
)
await printBalancesToConsole()
await smartContract.sendTransaction({ from: client, value: web3.toWei(0.1, 'ether') })
await printBalancesToConsole()
await smartContract.sendPayAmountToTasker({ from: deployer })
await printBalancesToConsole()
}
Sau đó ta dùng câu lệnh bên dưới là có thể deploy được Smart Contract mà chúng ta vừa viết lên mạng blockchain của Ganache.
truffle migrate
Như vậy là chúng ta đã hoàn thành được mục tiêu là viết và deploy thành công Smart Contract lên mạng blockchain. Tuy nhiên vẫn còn nhiều phần kiến thức mà phạm vi bài viết chưa giới thiệu. Ví dụ ở code của phần deploy chúng ta sử dụng thư viện web3, thư viện này có chứa nhiều phương thức, ý nghĩa của những phương thức đó là gì? Smart Contract được thực thi như thế nào? Chúng ta có thể tự tạo ra 1 loại tiền ảo của chính mình hay không? Những nội dung đó chúng ta sẽ tìm hiểu trong những loạt bài sắp tới.
V. Link tham khảo
https://solidity.readthedocs.io/en/v0.5.0/
https://truffleframework.com/ganache