簡單做一個模擬挖礦收益概念的範例

https://docs.openzeppelin.com/contracts/4.x/erc20-supply

固定提供(非常不推薦這樣撰寫,現在新版好像不能樣做了)

contract ERC20FixedSupply is ERC20 {
	constructor() {
		totalSupply += 1000;
		balances[msg.sender] += 1000;	
	}
}

模組化機制

contract MinerRewardMinter {
    ERC20PresetMinterPauser _token;

    constructor(ERC20PresetMinterPauser token) {
        _token = token;
    }

    function mintMinerReward() public {
        _token.mint(block.coinbase, 1000);
    }
}

使用ERC20PresetMinterPauser並授予該minter合約的角色,我們可以透過這樣的方式來分派多的合約分派,但通常鑄造的部分是不會對外使用的。(很重要特別提出來)

獎勵礦工

contract ERC20WithMinerReward is ERC20 {
    constructor() ERC20("Reward", "RWD") {}

    function mintMinerReward() public {
        _mint(block.coinbase, 1000); // block.coinbase(address) 礦工位址
    }
}

能看到mintMinerReward礦工協助呼叫此函數通過 _mint 發放1000 RWD 獎勵

如果想測試可以把block.coinbase 改成 msg.sender 來感受一下

但實際上因該下面這樣

自動化獎勵

contract ERC20WithAutoMinerReward is ERC20 {
    constructor() ERC20("Reward", "RWD") {}

    function _mintMinerReward() internal {
        _mint(block.coinbase, 1000);
    }

    function _beforeTokenTransfer(address from, address to, uint256 value) internal virtual override {
        if (!(from == address(0) && to == block.coinbase)) {
          _mintMinerReward();
        }
        super._beforeTokenTransfer(from, to, value);
    }
}

會發現_beforeTokenTransfer在挖礦前其實獎勵就會發送了!!