[Ethereum] 独自トークンの発行

### gethを起動
geth –networkid “15” –nodiscover –port 30304 –datadir ./ console 2>> ./geth_err.log

### RPCを有効にする必要がある
admin.startRPC(‘192.168.33.10’, 8545, ‘*’, ‘eth,net,web3’)
admin.stopRPC()

### broser-solidity
$ git clone https://github.com/ethereum/browser-solidity.git
$ php -S 192.168.33.10:8000
Solidity IDEを起動(index.htmlにアクセス)し、EnvironmentでWeb3Providerで192.168.33.10:8545に接続する

アカウントを見ると、private netで作成したアカウントと残高が一致している

broser/211220_MyToken.sol

pragma solidity ^0.4.16;

interface tokenRecipient { function receiveApproval(address _from, uint256 _value, address _token, bytes _extraData) public; }

contract TokenERC20 {
    // Public variables of the token
    string public name;
    string public symbol;
    uint8 public decimals = 18;
    // 18 decimals is the strongly suggested default, avoid changing it
    uint256 public totalSupply;

    // This creates an array with all balances
    mapping (address => uint256) public balanceOf;
    mapping (address => mapping (address => uint256)) public allowance;

    // This generates a public event on the blockchain that will notify clients
    event Transfer(address indexed from, address indexed to, uint256 value);

    // This notifies clients about the amount burnt
    event Burn(address indexed from, uint256 value);

    /**
     * Constrctor function
     *
     * Initializes contract with initial supply tokens to the creator of the contract
     */
    function TokenERC20(
        uint256 initialSupply,
        string tokenName,
        string tokenSymbol
    ) public {
        totalSupply = initialSupply * 10 ** uint256(decimals);  // Update total supply with the decimal amount
        balanceOf[msg.sender] = totalSupply;                // Give the creator all initial tokens
        name = tokenName;                                   // Set the name for display purposes
        symbol = tokenSymbol;                               // Set the symbol for display purposes
    }

    /**
     * Internal transfer, only can be called by this contract
     */
    function _transfer(address _from, address _to, uint _value) internal {
        // Prevent transfer to 0x0 address. Use burn() instead
        require(_to != 0x0);
        // Check if the sender has enough
        require(balanceOf[_from] >= _value);
        // Check for overflows
        require(balanceOf[_to] + _value > balanceOf[_to]);
        // Save this for an assertion in the future
        uint previousBalances = balanceOf[_from] + balanceOf[_to];
        // Subtract from the sender
        balanceOf[_from] -= _value;
        // Add the same to the recipient
        balanceOf[_to] += _value;
        Transfer(_from, _to, _value);
        // Asserts are used to use static analysis to find bugs in your code. They should never fail
        assert(balanceOf[_from] + balanceOf[_to] == previousBalances);
    }

    /**
     * Transfer tokens
     *
     * Send `_value` tokens to `_to` from your account
     *
     * @param _to The address of the recipient
     * @param _value the amount to send
     */
    function transfer(address _to, uint256 _value) public {
        _transfer(msg.sender, _to, _value);
    }

    /**
     * Transfer tokens from other address
     *
     * Send `_value` tokens to `_to` on behalf of `_from`
     *
     * @param _from The address of the sender
     * @param _to The address of the recipient
     * @param _value the amount to send
     */
    function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) {
        require(_value <= allowance[_from][msg.sender]);     // Check allowance
        allowance[_from][msg.sender] -= _value;
        _transfer(_from, _to, _value);
        return true;
    }

    /**
     * Set allowance for other address
     *
     * Allows `_spender` to spend no more than `_value` tokens on your behalf
     *
     * @param _spender The address authorized to spend
     * @param _value the max amount they can spend
     */
    function approve(address _spender, uint256 _value) public
        returns (bool success) {
        allowance[msg.sender][_spender] = _value;
        return true;
    }

    /**
     * Set allowance for other address and notify
     *
     * Allows `_spender` to spend no more than `_value` tokens on your behalf, and then ping the contract about it
     *
     * @param _spender The address authorized to spend
     * @param _value the max amount they can spend
     * @param _extraData some extra information to send to the approved contract
     */
    function approveAndCall(address _spender, uint256 _value, bytes _extraData)
        public
        returns (bool success) {
        tokenRecipient spender = tokenRecipient(_spender);
        if (approve(_spender, _value)) {
            spender.receiveApproval(msg.sender, _value, this, _extraData);
            return true;
        }
    }

    /**
     * Destroy tokens
     *
     * Remove `_value` tokens from the system irreversibly
     *
     * @param _value the amount of money to burn
     */
    function burn(uint256 _value) public returns (bool success) {
        require(balanceOf[msg.sender] >= _value);   // Check if the sender has enough
        balanceOf[msg.sender] -= _value;            // Subtract from the sender
        totalSupply -= _value;                      // Updates totalSupply
        Burn(msg.sender, _value);
        return true;
    }

    /**
     * Destroy tokens from other account
     *
     * Remove `_value` tokens from the system irreversibly on behalf of `_from`.
     *
     * @param _from the address of the sender
     * @param _value the amount of money to burn
     */
    function burnFrom(address _from, uint256 _value) public returns (bool success) {
        require(balanceOf[_from] >= _value);                // Check if the targeted balance is enough
        require(_value <= allowance[_from][msg.sender]);    // Check allowance
        balanceOf[_from] -= _value;                         // Subtract from the targeted balance
        allowance[_from][msg.sender] -= _value;             // Subtract from the sender's allowance
        totalSupply -= _value;                              // Update totalSupply
        Burn(_from, _value);
        return true;
    }
}

SettingでSolidity versionを0.4.16に合わせる
※Compilerのバージョンが異なると、実行できない

TimeCoinを1億枚発行します
100000000, “Timecoin”, “TMCN”

transferしてみます。
transfer: “0x87b2d715dafdfa88da7d76b25069162153967e23″, 2000
personal.unlockAccount(eth.accounts[0],”pass1”)
miner.start()

なぜだろう、、、
まあ、tokenの発行方法はなんとなくわかりました。

Running 3 transaction(s) …
(0) {
“value”: “0”,
“parameters”: [
1000
],
“abi”: “0x99ff0d9125e1fc9531a11262e15aeb2c60509a078c4cc4c64cefdfb06ff68647”,
“contractName”: “Token”,
“bytecode”: “6060604052341561000f57600080fd5b6040516020806102a9833981016040528080519060200190919050505b806000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b505b610228806100816000396000f30060606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806370a082311461004957806390b98a1114610096575b600080fd5b341561005457600080fd5b610080600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506100f0565b6040518082815260200191505060405180910390f35b34156100a157600080fd5b6100d6600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610108565b604051808215151515815260200191505060405180910390f35b60006020528060005260406000206000915090505481565b6000816000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054101561015957600090506101f6565b816000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540392505081905550816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550600190505b929150505600a165627a7a72305820ce860e3f5be7186124af4f5b1b7d2f2bce526d21e1473f9ae5860d1b9e8275610029”,
“linkReferences”: {},
“name”: “”,
“type”: “constructor”,
“from”: “0x6752a913de4f4530ed3f071371db8d70acc42fce”
}
(0) data: 6060604052341561000f57600080fd5b6040516020806102a9833981016040528080519060200190919050505b806000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b505b610228806100816000396000f30060606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806370a082311461004957806390b98a1114610096575b600080fd5b341561005457600080fd5b610080600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506100f0565b6040518082815260200191505060405180910390f35b34156100a157600080fd5b6100d6600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610108565b604051808215151515815260200191505060405180910390f35b60006020528060005260406000206000915090505481565b6000816000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054101561015957600090506101f6565b816000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540392505081905550816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550600190505b929150505600a165627a7a72305820ce860e3f5be7186124af4f5b1b7d2f2bce526d21e1473f9ae5860d1b9e827561002900000000000000000000000000000000000000000000000000000000000003e8

[block:1425 txIndex:0] from:0x675…42fce, to:TokenERC20.transfer(address,uint256) 0x9dc…09b6e, value:0 wei, 1 logs, data:0xa90…007d0, hash:0x69f…e3972
Details
Debug
from 0x6752a913de4f4530ed3f071371db8d70acc42fce
to TokenERC20.transfer(address,uint256) 0x9dc215338fac216e5e04221c9aed78a31a609b6e
gas 53034 gas

transaction cost 53034 gas
hash 0x69fbfb4cbc25afc761ef1cbbe814fbf35f01c1f153cf73f97e090575675e3972
input 0xa9059cbb00000000000000000000000087b2d715dafdfa88da7d76b25069162153967e2300000000000000000000000000000000000000000000000000000000000007d0
decoded input {
“address _to”: “0x87b2d715dafdfa88da7d76b25069162153967e23”,
“uint256 _value”: “2000”
}
decoded output –
logs [
{
“topic”: “0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef”,
“event”: “Transfer”,
“args”: [
“6752a913de4f4530ed3f071371db8d70acc42fce”,
“87b2d715dafdfa88da7d76b25069162153967e23”,
“2000”
]
}
]
value 0 wei

ああああああああああ、できたー
scenario.jsonを保存してから実行しないとpendingになるのね。理解した。