[Ethereum] CryptoKitiies

CryptoKitties
https://www.cryptokitties.co/

ソースコード
-> contractが公開されている
https://etherscan.io/address/0x06012c8cf97bead5deae237070f9587f8e7a266d#code

contractを継承

contract KittyAccessControl
contract KittyBase is KittyAccessControl
contract KittyOwnership is KittyBase, ERC721
contract KittyBreeding is KittyOwnership
contract KittyAuction is KittyBreeding
contract KittyMinting is KittyAuction
contract KittyCore is KittyMinting
function setGeneScienceAddress(address _address) external onlyCEO {
        GeneScienceInterface candidateContract = GeneScienceInterface(_address);

        // NOTE: verify that a contract is what we expect - https://github.com/Lunyr/crowdsale-contracts/blob/cfadd15986c30521d8ba7d5b6f57b4fefcc7ac38/contracts/LunyrToken.sol#L117
        require(candidateContract.isGeneScience());

        // Set the new contract address
        geneScience = candidateContract;
    }

function giveBirth(uint256 _matronId)
        external
        whenNotPaused
        returns(uint256)
    {
        // Grab a reference to the matron in storage.
        Kitty storage matron = kitties[_matronId];

        // Check that the matron is a valid cat.
        require(matron.birthTime != 0);

        // Check that the matron is pregnant, and that its time has come!
        require(_isReadyToGiveBirth(matron));

        // Grab a reference to the sire in storage.
        uint256 sireId = matron.siringWithId;
        Kitty storage sire = kitties[sireId];

        // Determine the higher generation number of the two parents
        uint16 parentGen = matron.generation;
        if (sire.generation > matron.generation) {
            parentGen = sire.generation;
        }

        // Call the sooper-sekret gene mixing operation.
        uint256 childGenes = geneScience.mixGenes(matron.genes, sire.genes, matron.cooldownEndBlock - 1);

        // Make the new kitten!
        address owner = kittyIndexToOwner[_matronId];
        uint256 kittenId = _createKitty(_matronId, matron.siringWithId, parentGen + 1, childGenes, owner);

        // Clear the reference to sire from the matron (REQUIRED! Having siringWithId
        // set is what marks a matron as being pregnant.)
        delete matron.siringWithId;

        // Every time a kitty gives birth counter is decremented.
        pregnantKitties--;

        // Send the balance fee to the person who made birth happen.
        msg.sender.send(autoBirthFee);

        // return the new kitten's ID
        return kittenId;
    }

uint256 childGenes = geneScience.mixGenes(matron.genes, sire.genes, matron.cooldownEndBlock – 1); の mixGenesで配合している

[Blockchain] Ubuntu20.04・OpenSSLで秘密鍵公開鍵の操作

$ openssl version
OpenSSL 1.1.1f 31 Mar 2020

### 秘密鍵の作成
$ openssl ecparam -genkey -name secp256k1 -out private.pem
// ecparamは楕円曲線暗号における楕円曲線パラメータに関するサブコマンド
$ cat private.pem
—–BEGIN EC PARAMETERS—–
BgUrgQQACg==
—–END EC PARAMETERS—–
—–BEGIN EC PRIVATE KEY—–
MHQCAQEEINB5OV0K2ggkM2a0bmVTcj7FioqK5TDI9NJAxgOUjcFOoAcGBSuBBAAK
oUQDQgAELnHK99GtgUL9F3Q5YSwYa5ZdI8uY0P5diBTZZN4Ld7feo13zqYO9oQm3
G1YHB2ITeG81+KridKnVOzDk0RwA7w==
—–END EC PRIVATE KEY—–

### 公開鍵の作成
$ openssl ec -in private.pem -pubout -out public.pem
// echは楕円曲線暗号に関するサブコマンド
read EC key
writing EC key
$ cat public.pem
—–BEGIN PUBLIC KEY—–
MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAELnHK99GtgUL9F3Q5YSwYa5ZdI8uY0P5d
iBTZZN4Ld7feo13zqYO9oQm3G1YHB2ITeG81+KridKnVOzDk0RwA7w==
—–END PUBLIC KEY—–

### メッセージの作成、ハッシュ化
$ sha256sum test.txt | cut -c1-64 > hashed.txt
$ cat hashed.txt
d8aa344276524074fbfec2249bedb89a5ddccc9dc57504e92a9963f48bdf68d1

### verify
ハッシュ化した書類と秘密鍵でhashed.sigを作成し、公開鍵とhashed.sigで検証する
$ openssl dgst -SHA256 -sign private.pem hashed.txt > hashed.sig
// dgstはメッセージダイジェストを計算
$ ls
hashed.sig hashed.txt private.pem public.pem test.txt
$ openssl dgst -SHA256 -verify public.pem -signature hashed.sig hashed.txt
Verified OK

apostilleのことだね

[Ethereum] RemixとMetamask, Rapsten networkの使い方

1. ブラウザでRemixのサイトを開く
https://remix.ethereum.org/#optimize=false&runs=200&evmVersion=null&version=soljson-v0.8.7+commit.e28d00a7.js

2. 左メニューでイーサのマークをクリックし、Injected web3を選択する

3. contractを作成し、compilerを0.4.16に合わせてコンパイル

4. 1億tmcnをdeploy
100000000, “Timecoin”, “TMCN”

5. metamaskに通知が来るのでconfirm

6. deployされる

7. Etherscanでtransactionが確認できる

8. Metamaskのtoken importでcontractのhashを入力し、トークンをインポートする

9. MyEtherWalletにログイン
timecoin, tmcnが入っているのがわかる

10. tachyon walletをインストール

11. QRコードでコントラクトをQRコード化する
QRコード作成サイト
https://www.cman.jp/QRcode/qr_make/
{ERC20:0xeE19196D02D69012c4e7Ce962B528360681F8E36}

12. tachyon walletで networkをRopstenにして、新しい通貨を追加

13. MetaMaskからtachyon walletのアドレスに向けて送信

14. tachyon walletで受け取り

おおおおおおおおおおおおおおおおおお
大分概念を理解した^^
Ethを動かした方が早いですね

[Ethereum] web3.jsをhtml内で使用する

web3.jsはcdnで実装する
weiからethに変更するのも、web3.utils.fromWei(result, ‘ether’);で一発

<div class="container">
		<a href="/"><h1 class="title">My Ethereum</h1></a><br>
		<nav class="panel">
		  <p class="panel-heading">
		    Balance
		  </p>
		  <div class="box">
		    <div class="field">
				<label class="label">Ethereum Address</label>
				<div class="control">
					<input class="input" type="text" id="wallet" placeholder="wallet address">
				</div>
			</div>
		  </div>
		  
		 </nav>
		<p>Please enter the wallet address and press the button</p>
		<input type="submit" class="button is-link" id="btn" value="Check" onclick="OnButtonClick();">
		<br>
		<br>
		<br>
		
		<article class="message">
		<div class="message-header">
		    <p>Balance</p>
		  </div>
		  <div class="message-body">
		  	<div id="resArea"></div>
		    
		  </div>
		</article>
		<br>
		<a href="" target="_blank">BLOCK Chain explore</a>
	</div>
	<script src="https://cdnjs.cloudflare.com/ajax/libs/web3/1.7.0-rc.0/web3.min.js"></script>
	<script>
		let resArea = document.getElementById('resArea');
		let wallet = document.getElementById('wallet');

		function OnButtonClick() {
			main();	
			
		}
		async function main(){
			var web3 = new Web3();
			web3.setProvider(new web3.providers.HttpProvider('http://192.168.33.10:8545'));
			web3.eth.getBalance(wallet.value).then((result, error) => {
				const balance = web3.utils.fromWei(result, 'ether');
				console.log(balance);
				resArea.innerHTML = balance + " eth";
			});
			
		}
		
	</script>

なるほどー

送信する場合も同じ

<script src="https://cdnjs.cloudflare.com/ajax/libs/web3/1.7.0-rc.0/web3.min.js"></script>
	<script>
		let resArea = document.getElementById('resArea');
		let wallet = document.getElementById('wallet');
		let volume = document.getElementById('volume');

		function OnButtonClick() {
			main();	
			
		}
		async function main(){
			var web3 = new Web3();
			web3.setProvider(new web3.providers.HttpProvider('http://192.168.33.10:8545'));
			web3.eth.sendTransaction({from: "0x6752a913de4f4530ed3f071371db8d70acc42fce", to:wallet.value, value: volume.value});
			web3.eth.getBalance(wallet.value).then((result, error) => {
				console.log(result);
				resArea.innerHTML = result;
			});
			
		}
		
	</script>

自分で作ると時間かかるね

[Ethereum] 独自トークンをMetaMaskに送信

Metamaskで新規 RPC URLにhttp://192.168.33.10:8545 とする。
chainIDはgenesis.jsonの10で設定する

  "config": {
        "chainId": 10,
        "homesteadBlock": 0,
        "eip150Block": 0,
        "eip155Block": 0,
        "eip158Block": 0
    },

import tokenでbroser-solidityのコントラクトのアドレスと作成したコインを入力する

transferでmetamaskのアドレスを入力する
personal.unlockAccount(eth.accounts[0],”pass1″)
“0x71c9f1D5bE00173ae7B774bDBE2112cdD03C5C92”, 20000000

transactionが生成される

メタマスクに独自トークンが送信された

Ropstenでやりたいが、Ethの取得が中々うまくいかない。。
が、基本的な仕組みは理解した

[Ethereum] web3.jsによりgethを操作

– web3.jsとは、Ethereumネットワーク上でデータを扱えるようにするライブラリ
– HTTPまたはIPC接続を利用して、ローカルまたはリモートのEthereumブロックチェーンのnodeとやり取りできる

$ npm install web3@0.20.0

### geth起動
$ geth –networkid “15” –nodiscover –port 30304 –datadir ./ console 2>> ./geth_err.log
> admin.startRPC(‘0.0.0.0’, 8545, ”, ‘eth,net,web3,personal’)
true

### web3によるアカウント作成

var Web3 = require('web3');
var web3 = new Web3();
web3.setProvider(new web3.providers.HttpProvider('http://192.168.33.10:8545'));
var _account = web3.personal.newAccount("test");
console.log(_account)

$ node create_account.js
0x41a4a74bfd4659b742d45d4cafe2bbbd0c6b5d65

### 残高確認

var Web3 = require('web3');
var web3 = new Web3();
web3.setProvider(new web3.providers.HttpProvider('http://192.168.33.10:8545'));
var _balance = web3.eth.getBalance("0x6752a913de4f4530ed3f071371db8d70acc42fce");
console.log(_balance)

$ node getBalance.js
BigNumber { s: 1, e: 22, c: [ 322200000, 21000000000000 ] }

### 送金

var Web3 = require('web3');
var web3 = new Web3();
web3.setProvider(new web3.providers.HttpProvider('http://192.168.33.10:8545'));
var _sendTransaction = web3.eth.sendTransaction({from: "0x6752a913de4f4530ed3f071371db8d70acc42fce", to:"0x87b2d715dafdfa88da7d76b25069162153967e23", value:200});
console.log(_sendTransaction)

実行する前に、アカウントをアンロックする
> personal.unlockAccount(eth.accounts[0],”pass1″)
true

$ node sendTransaction.js
0x61a0c52aa933c7d5448928d322b7c545726037c65a982d83f8c1669c1fd837ac

### balanceの確認

var Web3 = require('web3');
var web3 = new Web3();
web3.setProvider(new web3.providers.HttpProvider('http://192.168.33.10:8545'));
web3.eth.defaultAccount=web3.eth.accounts[0]

var abi = [{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[],"payable":false,"type":"function"},{"inputs":[{"name":"initialSupply","type":"uint256"}],"payable":false,"type":"constructor"}];

var contract_address = "0x5e722e71c6bd4127eec0b4fa8c2e415755985826"
var balance_address = "0x87b2d715dafdfa88da7d76b25069162153967e23"

var _balanceOf = web3.eth.contract(abi).at(contract_address).balanceOf(balance_address);
console.log(_balanceOf);

$ node balanceOf.js
BigNumber { s: 1, e: 5, c: [ 200200 ] }

contractのaddressがあるのね。

### transfer

var Web3 = require('web3');
var web3 = new Web3();
web3.setProvider(new web3.providers.HttpProvider('http://192.168.33.10:8545'));
web3.eth.defaultAccount=web3.eth.accounts[0]

var abi = [{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[],"payable":false,"type":"function"},{"inputs":[{"name":"initialSupply","type":"uint256"}],"payable":false,"type":"constructor"}];

var contract_address = "0x5e722e71c6bd4127eec0b4fa8c2e415755985826"
var transfer_address = "0x87b2d715dafdfa88da7d76b25069162153967e23"
var value = 1000

var _transfer = web3.eth.contract(abi).at(contract_address).transfer.sendTransaction(transfer_address, value);
console.log(_transfer);

$ node transfer.js
0xda2cec8a827e4890920a0d28728e7cc162b807c2bf34b7017ad9e43fab19a6c9

$ node balanceOf.js
BigNumber { s: 1, e: 5, c: [ 201200 ] }

このweb3.jsはかなり便利

[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になるのね。理解した。

[Ethereum] GethでETH送金

### ETH送金
> web3.fromWei(eth.getBalance(eth.accounts[1]), “ether”)
0
> web3.fromWei(eth.getBalance(eth.accounts[0]), “ether”)
265

– アカウントのロック解除
> personal.unlockAccount(eth.accounts[0],”pass1″)
true

– ETH送金
> eth.sendTransaction({from: eth.accounts[0], to: eth.accounts[1], value: web3.toWei(10, “ether”)})
“0x2c0c90b18598551e678fa0eddef034c5e7759c2750927abae38cef9486814c0c”

– マイニングする(マイニングをしないと送金されない ブロックが生成されてないからか)
> miner.start()
null
> eth.mining
true
> eth.hashrate
16082
> web3.fromWei(eth.getBalance(eth.accounts[1]),”ether”)
10
> miner.stop()
null

### トランザクション、ブロック
> eth.getTransaction(“0x2c0c90b18598551e678fa0eddef034c5e7759c2750927abae38cef9486814c0c”)
{
blockHash: “0xc0f7e2bffbeece31a4a890f6d4b554a7b79f323543a3d146463ad78b9d9a6198”,
blockNumber: 54,
from: “0x6752a913de4f4530ed3f071371db8d70acc42fce”,
gas: 21000,
gasPrice: 1000000000,
hash: “0x2c0c90b18598551e678fa0eddef034c5e7759c2750927abae38cef9486814c0c”,
input: “0x”,
nonce: 0,
r: “0x32d8d13541808080dabefbc39df215e01516ead9115be54de16133d60e9104d8”,
s: “0x3d1e49ba781eaa5ccae9683f8c2e2225e06aed1bdb736514bc29cf551923be33”,
to: “0x87b2d715dafdfa88da7d76b25069162153967e23”,
transactionIndex: 0,
type: “0x0”,
v: “0x38”,
value: 10000000000000000000
}

> eth.getBlock(“54”)
{
difficulty: 131072,
extraData: “0xd883010a0d846765746888676f312e31372e32856c696e7578”,
gasLimit: 3311539,
gasUsed: 21000,
hash: “0xc0f7e2bffbeece31a4a890f6d4b554a7b79f323543a3d146463ad78b9d9a6198”,
logsBloom: “0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000”,
miner: “0x6752a913de4f4530ed3f071371db8d70acc42fce”,
mixHash: “0x08bb6af9df543835877260cd890a8e234383269fcefaa0b03f6cec0aea87ae18”,
nonce: “0x77ca71556eca292f”,
number: 54,
parentHash: “0x14be3c7269afab1eb01e221dfe05283d21a574cabb707571a464f5d3e106210a”,
receiptsRoot: “0xaa48dd6dc5cf21faf1da3ed77d1b91e087e446ad7485ac4d8b737c53e6faf2c1”,
sha3Uncles: “0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347”,
size: 648,
stateRoot: “0xc76aaf77c4d6a10159b8dd505eef0e2c3c3b00afcf3ef826db794d895e8b3c84”,
timestamp: 1639974714,
totalDifficulty: 7294014,
transactions: [“0x2c0c90b18598551e678fa0eddef034c5e7759c2750927abae38cef9486814c0c”],
transactionsRoot: “0xce5ed8b87e501a3061bf6520df5c76ee0847426e8ad05e647f847fca0e5b4acf”,
uncles: []
}

### 手数料の確認
> personal.newAccount(“pass3”)
“0x3c0fdb1594e99dc9c0cdd65ea8f6c2631b838553″
> eth.getBalance(eth.accounts[1])
10000000000000000000
> eth.getBalance(eth.accounts[2])
0

> personal.unlockAccount(eth.accounts[1],”pass2″)
true
> eth.sendTransaction({from: eth.accounts[1], to: eth.accounts[2], value: web3.toWei(6,”ether”)})
“0xb1a53e635f9c6cec886b23d31a8184cb3490c0bed8b2348267d49d663b2b5bd1”
> miner.start()
> eth.getBalance(eth.accounts[2])
6000000000000000000
> miner.stop()
null
> eth.getBalance(eth.accounts[1])
3999979000000000000

手数料がかかるアカウントと、かからないアカウントがあるのね

[Ethereum] Gethでマイニング

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

### マイニング
– アカウントの作成(送金をする為に2つ作る)
> personal.newAccount(“pass1”)
“0x6752a913de4f4530ed3f071371db8d70acc42fce”
> personal.newAccount(“pass2”)
“0x87b2d715dafdfa88da7d76b25069162153967e23”

マイニングを受け取るアカウント
> eth.coinbase
“0x6752a913de4f4530ed3f071371db8d70acc42fce”

#### アカウントの変更
> miner.setEtherbase(eth.accounts[1])
true
> eth.coinbase
“0x87b2d715dafdfa88da7d76b25069162153967e23”

#### ブロックとアカウント残高を確認
> eth.blockNumber
0
> eth.getBalance(eth.accounts[0])
0
> eth.getBalance(eth.accounts[1])
0

#### マイニングスタート
> miner.start()
null
> eth.mining
true
> eth.hashrate
24455
> eth.blockNumber
19
> eth.blockNumber
46

#### マイニングストップ
> miner.stop()
null

> eth.getBalance(eth.accounts[0])
265000000000000000000
> web3.fromWei(eth.getBalance(eth.accounts[0]), “ether”)
265

なんかできてるっぽい
コマンドラインで操作するのね
Goで書いていくのかと思ってたわ