iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 13
0

導言

本次範例使用了ERC20,ERC20是目前發行Token最主要的標準,基本上目前在市面上所使用的Token都遵循ERC20的標準所建立,有些公司透過ERC20發行自己的Token並發起ICO,

程式碼

pragma solidity^0.4.25;
contract ERC20_interface{
    address owner;
    mapping(address=>uint) balances;
    mapping(address=>mapping(address=>uint)) allowed;
    event Approval(
        address indexed owner,
        address indexed spender,
        uint value
    );
    event Tansfer(
        address indexed from, 
        address indexed to, 
        uint value
    );

    function balanceOf() public view returns(uint256);
    function allowance(address _owner,address _spender) public view returns(uint256);
    function transfer(address _to,uint _value) public returns(bool);
    function transferFrom(address _owner,address _spender,uint _value) public returns(bool);
    function approve(address _spender,uint _value) public returns(bool);
}
contract ERC20 is ERC20_interface{
    uint public totalSupply;
    constructor(uint _initialSupply)public{
        totalSupply = _inititalSupply;
        owner = msg.sender;
        balances[owner] = totalSupply;
    }

    function balanceOf(address _owner) public view returns(uint256){
        return balances[_owner];
    }
    function allowance(address _owner,address _spender) public view returns(uint256){
        return allowed[_owner][_spender];
    }
    function transfer(address _to,uint _value) public returns(bool){
        require(balances[msg.sender] >= _value);
        balances[msg.sender] -= _value;
        balances[_to] += _value;
        emit Transfer(msg.sender,_spender,_value);
        return true;
    }
    function transferFrom(address _owner,address _spender,uint _value) public returns(bool){
        uint allowance = allowed[_owner][_spender];
        require(balances[_owner] >= _value,"owner haven't enough money to transfer");
        require(_value <= allowance,"_value can't more than allowance");
        balances[_owner] -= _value;
        balances[_spender] += _value;
        allowed[_owner][_spender] -= _value;
        emit Transfer(_owner,_spender,_value);
        return true;
    }
    function approve(address _spender,uint _value) public returns(bool){
        
        allowed[msg.sender][_spender] += _value;
        emit Approval(msg.sender,_spender,_value);
        return true;
    }
}

解說

contract ERC20_interface{...}
contract ERC20 is ERC20_interface{...}

在同一份solidity script,可以將不同功能的function以contract符號區分,排序下面的contract可以繼承排序上面的contract,寫法是contract SecondContract is FirstContract{...},當整份script compile之後,SecondContract的ABI會有FirstContract所有的function,當deploy SecondContract到blockchain的時候,也就可以在同一個contract address執行原本在sciprt上拆分的contract。

address owner;

目前這個ERC20 Token contract的擁有者,設定是最一開始deploy合約的人擔任,在這個contract的設定,owner會有所有的token,owner可以將Token轉送給指定的address(帳戶))

mapping(address=>uint) balances;

在這個contract的設定,balances代表一個帳戶所擁有的餘額,在程式的表示上長這樣,balances[address]=value,也就是這個address 會mapping到 uint的單位,個人覺得有點像object,可以想像是balances = {address : uint},因為mapping 為key-value形式,所以在宣告上可以這樣解釋;mapping 屬性 (key => value) MappingVariableName

mapping(address=>mapping(address=>uint)) allowed;

allowed表示允許address1轉帳給address2多少錢,完整陳述為 allowed[address1][address2] = uint,和上一個balances比較不同的是,value的位置塞一個mapping(address=>uint)),所以看起來像是allowed = { address1 :{address2 : uint}}

event Approval(...);

只在執行允許轉帳的時候會被觸發,被觸發時會發送將訊息內容(轉送者,接收者,額度))放到transaction receipt 的log,公開在blockchain上

event Tansfer(...);

只在執行交易的時候會被觸發,被觸發時會發送將訊息內容(轉送者,接收者,額度))放到transaction receipt 的log,公開在blockchain上

function balanceOf() public view returns(uint256);

查詢目前使用的帳戶擁有多少餘額,只針對查詢呼叫function的address之餘額

function allowance(address _owner,address _spender) public view returns(uint256);

查詢owner給予spender多少轉帳額度

function transfer(address _to,uint _value) public returns(bool);

直接交易的function,由傳送者呼叫function,執行過程會先檢查傳送者所持有的餘額是不是大於或等於傳送的金額,如果符合,將會確實扣除傳送者所持有的餘額,並增加接收者的餘額,最後會發布交易訊息Transfer event到transaction receipt,公布在blockchain上

function transferFrom(address _owner,address _spender,uint _value) public returns(bool);

和approve function搭配使用,transferFrom為確實執行轉帳交易的function,執行過程會先檢查傳送者的餘額是不是大於或等於指定的金額balances[owner]>=_value,再來檢查指定傳送的金額不得超過先前所設定的轉帳額度allowed[owner][spender] >= _value,如果都符合條件,扣除和增加雙方的餘額,並扣除先前准許的轉帳額度,最後發布交易訊息Transfer event 到transaction receipt,公布在blockchain上

function approve (address _spender,uint _value) public returns(bool);

為轉帳程序第一步,紀錄雙方的轉帳行為,當傳送者准許轉帳給接收者,將會執行approve function ,並將雙方address 和轉帳額度,放到mapping allowed紀錄轉帳行為,最後發布轉帳允許訊息Approve event到transaction receipt,公布在blockchain上


上一篇
Day11-P2P
下一篇
Day13-Token
系列文
30天30個Smart contract 20

尚未有邦友留言

立即登入留言