読者です 読者をやめる 読者になる 読者になる

SmartContractをデプロイした場合にBlockにどのように情報が残るのか

SmartContractをデプロイした場合にEthereumネットワークのBlockにどのように情報が残るのかやってみます。

対象とするContractのソースはこれ。以前インストールしたCOSMOの中のサンプルCoinを使います。

contract Coin {
    address minter;
    mapping (address => uint) balances;

    event Send(address from, address to, uint value);

    function Coin() {
        minter = msg.sender;
    }
    function mint(address owner, uint amount) {
        if (msg.sender != minter) return;
        balances[owner] += amount;
    }
    function send(address receiver, uint amount) {
        if (balances[msg.sender] < amount) return;
        balances[msg.sender] -= amount;
        balances[receiver] += amount;
        Send(msg.sender, receiver, amount);
    }
    function queryBalance(address addr) constant returns (uint balance) {
        return balances[addr];
    }
        
}

デプロイボタンを押して少し待つと・・・・

Your contract is being deployed. This may take a minute...
Contract deploying at 0xe74698567b7b89310afa9fd869ffd5f09786a471

さてこのときに裏で何が起こっているか追ってみましょう。

コンパイルしたブロックの中身

> eth.getBlock( 574 )
{
  difficulty: 131072,
  extraData: "0xd783010400844765746887676f312e352e31856c696e7578",
  gasLimit: 3141592,
  gasUsed: 123297,
  hash: "0x0804900f56e957fff59d8d6713861d8a537c5919bd12114e6435a394af6b0970",
  logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  miner: "0x421c0774f55fa2171050a37a05d95bcfcf64b39c",
  nonce: "0x7d6798488bb00ce5",
  number: 574,
  parentHash: "0x76dfd03361a527c06db5feb171e2fa02132a0ddd396e3ed347026776753229f3",
  receiptRoot: "0x38845df61c324153948449834d76e063e52efbe6f422f18e9205ee1bfa66c15c",
  sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
  size: 967,
  stateRoot: "0xd63f10aeb7a6d8d7d474f9847bf8b307d243ad7992d7ae932a5a52c61fc4dcfe",
  timestamp: 1452069512,
  totalDifficulty: 76077385,
  transactions: ["0xef9d4eab6e12afee4ac4984c61b887e2929103f7b388efd0beb7635263b5ffd0"],
  transactionsRoot: "0x23492a3950f3738922c92e84bf7be321d3c0a189a85ff2bb392b56e44417a9d6",
  uncles: []
}

特に変わったところはありませんが、トランザクションを発行していないのに
transactions: ["0xef9d4eab6e12afee4ac4984c61b887e2929103f7b388efd0beb7635263b5ffd0"]
トランザクションがあります。このトランザクションの中身を追ってみると

eth.getTransactionFromBlock

> eth.getTransactionFromBlock( 574 )
{
  blockHash: "0x0804900f56e957fff59d8d6713861d8a537c5919bd12114e6435a394af6b0970",
  blockNumber: 574,
  from: "0x11b00fff3570ac74d66192ffc18d3621b0b3dc4e",
  gas: 1800000,
  gasPrice: 50000000000,
  hash: "0xef9d4eab6e12afee4ac4984c61b887e2929103f7b388efd0beb7635263b5ffd0",
  input: "0x606060405260008054600160a060020a0319163317905561012e806100256000396000f300606060405260e060020a600035046337f42841811461003157806340c10f1914610056578063d0679d341461007c575b005b600160a060020a03600435166000908152600160205260409020546060908152602090f35b61002f600435602435600054600160a060020a039081163391909116146100ab576100ca565b61002f600435602435600160a060020a033316600090815260016020526040902054819010156100ce576100ca565b600160a060020a03821660009081526001602052604090208054820190555b5050565b6040600081812080548490039055600160a060020a03808516808352929091208054840190553316606090815260809190915260a08290527f93eb3c629eb575edaf0252e4f9fc0c5ccada50496f8c1d32f0f93a65a8257eb59080a1505056",
  nonce: 25,
  to: null,
  transactionIndex: 0,
  value: 0
}

となっていて、fromはデプロイを指示した私のIDが入っておりinputに上記のソースのバイナリが入っています。
つまり、SmartContractのデプロイ自体もトランザクションとして管理されているのですね。
しかし、デプロイされたアドレスがここでは見えません。メッセージ的には「Contract deploying at 0xe74698567b7b89310afa9fd869ffd5f09786a471」となっているのでこいつを探しましょう。

eth.getTransactionReceipt

> eth.getTransactionReceipt("0xef9d4eab6e12afee4ac4984c61b887e2929103f7b388efd0beb7635263b5ffd0")
{
  blockHash: "0x0804900f56e957fff59d8d6713861d8a537c5919bd12114e6435a394af6b0970",
  blockNumber: 574,
  contractAddress: "0xe74698567b7b89310afa9fd869ffd5f09786a471",
  cumulativeGasUsed: 123297,
  gasUsed: 123297,
  logs: [],
  transactionHash: "0xef9d4eab6e12afee4ac4984c61b887e2929103f7b388efd0beb7635263b5ffd0",
  transactionIndex: 0
}

で、探してみるとここにいました。


つまりコントラクトをデプロイすると
デプロイされた事実がトランザクションとしてブロックに書き込まれ
トランザクションの中にデプロイ者とバイナリコードが保存され
トランザクションレシートにデプロイアドレスが記載される。
eth.getBlock() ⇒ eth.getTransactionFromBlock() ⇒ eth.getTransactionReceipt() の順に確認ですね。