Smart Contract

Smart Contract คืออะไร

Smart Contract คือ ชุดของ Code(function) และข้อมูล(state)ที่อยู่ในเฉพาะ Ethereum Blockchain ซึ่ง Contract Account สามารถส่ง Message ระหว่างกันได้ และ Smart Contract จะอยู่บน Ethereum Virtual Machine (EVM)

Smart Contract จะถูกเขียนด้วยภาษา Solidity หลังจากนั้นจะถูก Complie เป็น Bytecode แล้วนำ Bytecode เก็บลงใน Blockchain

Solidity

Solidity คือภาษาระดับสูงที่มีความคล้ายกับ Javascript ที่ใช้เขียน Smart Contract และ Complie เป็น Bytecode ซึ่งปัจจุบัน Solidity เป็นภาษาหลักของ Ethereum

Note

สามารถดูศึกษาข้อมูลเพิ่มเติมเกี่ยวกับ Solidity ได้ที่ Solidity Document

เขียน Smart Contract

ภาษา Solidity จะไม่เหมือนภาษาอื่นที่มีคำสั่ง Print เพื่อแสดงผลลัพธ์ที่ต้องการออกมา แต่จะแสดงออกมาในรูปแบบของ log event

pragma solidity >0.4.00 <0.6.0;

Smart Contract HelloWorld {
        event Print(string out);
        function() { Print("Hello, World!"); }
}

Code นี้จะทำให้ Blockchain แสดง log “Hello, World!” ออกมา

การนำ Smart Contract เก็บลงใน Blockchain

หลังจากเขียน Smart Contract ด้วยภาษา Solidity เรียบร้อยแล้วนำ Smart Contract ไป Complie เป็น Bytecode แล้วนำ Bytecode Deploy เข้าสู่ Blockchain หลังจากนั้น EVM จะทำการ Process แล้วเกิด Transaction ขึ้นโดย Transaction นี้สามารถอ้างถึงได้โดย Smart Contract Address

การเรียกใช้ Smart Contract โดย Web3

จากที่กล่าวในหัวข้อที่ผ่านมาว่า Smart Contract จะถูกแปลงเป็น Bytecode แล้วถูกเก็บลงใน Blockchain จะเห็นว่าไม่มีสิ่งใดใช้ในการอ้างอิงถึง function ที่อยู่ใน Smart Contract เลย ดังนั้นจึงมี ABI ขึ้นมา

ABI หรือ jsonInterface คือสิ่งที่บ่งบอกถึงโครงสร้างของ Smart Contract ที่คุณเขียนลงไป แต่มันจะไม่ได้ถูกเก็บลงใน Blockchain ด้วย คุณจึงจำเป็นต้องถือมันเองไว้ เพื่ออ้างอิงถึง function ที่อยู่ใน Smart Contract และมีเฉพาะผู้ที่เขียน Smart Contract นั้นๆหรือผู้ที่ Complie Code นั้นเท่านั้นที่รู้

สามารถศึกษาเพิ่มเติมได้ที่ https://web3js.readthedocs.io/en/1.0/web3-eth-contract.html

ตัวอย่าง Smart Contract เพื่อสร้าง Coin ใน Ethereum

pragma solidity >0.4.00 <0.6.0;

contract Coin {
    // The keyword "public" makes those variables
    // easily readable from outside.
    address public minter;
    mapping (address => uint) public balances;

    // Events allow light clients to react to
    // changes efficiently.
    event Sent(address from, address to, uint amount);

    // This is the constructor whose code is
    // run only when the Smart Contract is created.
    constructor() public {
        minter = msg.sender;
    }

    function mint(address receiver, uint amount) public {
        require(msg.sender == minter);
        require(amount < 1e60);
        balances[receiver] += amount;
    }

    function send(address receiver, uint amount) public {
        require(amount <= balances[msg.sender], "Insufficient balance.");
        balances[msg.sender] -= amount;
        balances[receiver] += amount;
        emit Sent(msg.sender, receiver, amount);
    }

    function checkbalances(address _account) external view returns (uint) {
        return balances[_account];
    }

}
  • address public minter คือการประกาศชนิดตัวแปร address มีขนาด 160 บิท ตัวแปรเป็นประเภท public ทำให้ตัวแปรเรียกใช้ได้ทั้งจากภายนอกและภายใน Smart Contract
  • mapping (address => uint) public balances; mapping คือชนิดของตัวแปร ที่มี key ใช้ในการอ้างอิงถึง value ในตัวอย่างคือ ใช้ address ในการอ้างอิงถึง uint
  • event Sent(address from, address to, uint amount); และ emit Sent(msg.sender, receiver, amount); การแสดงค่านั้นๆใน Blockchain โดยไม่มีค่าใช้จ่าย และเกิด Transaction
  • constructor() public { minter = msg.sender; } constructor คือฟังก์ชันเบื้องต้น จะทำงานแค่ตอน Deploy Smart Contract เท่านั้น ในที่นี้คือนำ address ที่ Deploy Smart Contract มาเก็บในตัวแปรชื่อ minter
  • require(msg.sender == minter); require เปรียบเสมือน if ถ้าเงื่อนไขใน require เป็น false จะทำให้การทำงานหยุดทันที ในตัวอย่างนี้คือ Account Address ที่เข้ามาทำงานในฟังก์ชันนี้ไม่ตรงกับ Account Address ที่ Deploy Smart Contract นี้จะไม่ทำงาน
  • function checkbalances(address _account) external view returns (uint) คือการประกาศฟังก์ชันประเภท external คือ ฟังก์ชันนี้สามารถเรียกใช้ได้เฉพาะ ภายนอก Smart Contract เท่านั้นและประเภท view returns คือ ฟังก์ชันนี้เป็นประเภทเรียกดูข้อมูลเท่านั้น จะส่งข้อมูลออกไปในชนิด uint และไม่เกิด Transaction

ตัวอย่างการใช้ Web3 สำหรับ Smart Contract เพื่อสร้าง Coin ใน Ethereum

สร้างไฟล์ index.html

<script src="https://cdn.jsdelivr.net/gh/ethereum/web3.js@1.0.0-beta.36/dist/web3.min.js" integrity="sha256-nWBTbvxhJgjslRyuAKJHK+XcZPlCnmIAAMixz6EefVk=" crossorigin="anonymous"></script>
<script type="text/javascript">
let web3 = new Web3("http://xxx.xxx.xx.xx:8545");
web3.setProvider(new web3.providers.HttpProvider("http://xxx.xxx.xx.xx:8545"));
async function run() {
    async function getCoinbase() {
        return await new Promise((resolve, reject) => {
            web3.eth.getCoinbase().then(async (cb)=>{
                await web3.eth.personal.unlockAccount(cb,"password");
                resolve(cb);
            })
        });
    }
    const coinbase = await getCoinbase();
    console.log(coinbase);
    let abi = [your abi];
    let address = [your address];
    const Contract = new web3.eth.contract( abi, address);
    console.log(Contract.methods);
    Contract.methods.mint(coinbase,20).send( {from: coinbase} ).then(console.log)
    Contract.methods.checkbalances(coinbase).call().then(console.log)
}
run();

</script>
http://xxx.xxx.xx.xx:8545 ใส่เลข IP และ Port ของ Node ที่ทำการ Deploy Smart Contract ขึ้นไป
await web3.eth.personal.unlockAccount(cb,"password"); password คือ Passphase ของ Account
let abi = [your abi]; แทนที่ [your_abi] ด้วย ABI ที่ได้จากการ Compile
let address = [your address]; แทนที่ [your address] ด้วย Contract Address ที่ได้จากการ Deploy
Contract.methods.mint(coinbase,20).send( {from: coinbase} ).then(console.log) คือ คำสั่งเรียกใช้ function mint ที่อยู่ใน Contract พร้อมทั้งเรียกดู Transaction Hash
Contract.methods.checkbalances(coinbase).call().then(console.log) คือ คำสั่งเรียกใช้ function checkbalance ที่อยู่ใน Smart Contract พร้อมทั้งเรียกดู output จาก function นั้น

วิธีใช้งานคือ run ไฟล์ index.html กด F12 แล้วกด F5 จะได้ผลลัพธ์ออกมา

Note

สามารถศึกษาข้อมูลเพิ่มเติมเกี่ยวกับ Web3 ได้ที่ Web3 Document