LoginSignup
2
2

More than 5 years have passed since last update.

スマートコントラクト開発でHello Worldをする(ethereum6)

Last updated at Posted at 2017-12-28

前回はこちら。スマートコントラクト開発の準備をする

vi HelloWorldOrg.sol 
HelloWorldOrg.sol
pragma solidity ^0.4.8;

contract HelloWorld {
    string public greeting;

    function HelloWorld(string _greeting){
        greeting = _greeting;
    }

    function setGreeting(string _greeting){
        greeting = _greeting;
    }

    function say() constant returns (string) {
        return greeting;
    }
}

改行文字を削除

cat HelloWorldOrg.sol | tr -d '\n' > HelloWorld.sol

文字列を出力

cat HelloWorld.sol

中身

pragma solidity ^0.4.8;contract HelloWorld {    string public greeting;        function HelloWorld(string _greeting){        greeting = _greeting;    }        function setGreeting(string _greeting){        greeting = _greeting;    }        function say() constant returns (string) {        return greeting;    }}

コンソール接続

geth attach rpc:http://localhost:8545

変数に上記の文字列を代入

source = 'pragma solidity ^0.4.8;contract HelloWorld {    string public greeting;        function HelloWorld(string _greeting){        greeting = _greeting;    }        function setGreeting(string _greeting){        greeting = _greeting;    }        function say() constant returns (string) {        return greeting;    }}'

コンパイル

sourceCompiled = eth.compile.solidity(source)
{
  /tmp/geth-compile-solidity839881623:HelloWorld: {
    code: "0x6060604052341561000f57600080fd5b60405161046d38038061046d833981016040528080519091019050600081805161003d929160200190610044565b50506100df565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061008557805160ff19168380011785556100b2565b828001600101855582156100b2579182015b828111156100b2578251825591602001919060010190610097565b506100be9291506100c2565b5090565b6100dc91905b808211156100be57600081556001016100c8565b90565b61037f806100ee6000396000f3006060604052600436106100565763ffffffff7c0100000000000000000000000000000000000000000000000000000000600035041663954ab4b2811461005b578063a4136862146100e5578063ef690cc014610138575b600080fd5b341561006657600080fd5b61006e61014b565b60405160208082528190810183818151815260200191508051906020019080838360005b838110156100aa578082015183820152602001610092565b50505050905090810190601f1680156100d75780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34156100f057600080fd5b61013660046024813581810190830135806020601f820181900481020160405190810160405281815292919060208401838380828437509496506101f495505050505050565b005b341561014357600080fd5b61006e61020b565b6101536102a9565b60008054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156101e95780601f106101be576101008083540402835291602001916101e9565b820191906000526020600020905b8154815290600101906020018083116101cc57829003601f168201915b505050505090505b90565b60008180516102079291602001906102bb565b5050565b60008054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156102a15780601f10610276576101008083540402835291602001916102a1565b820191906000526020600020905b81548152906001019060200180831161028457829003601f168201915b505050505081565b60206040519081016040526000815290565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106102fc57805160ff1916838001178555610329565b82800160010185558215610329579182015b8281111561032957825182559160200191906001019061030e565b50610335929150610339565b5090565b6101f191905b80821115610335576000815560010161033f5600a165627a7a72305820a8a39c563d28ad8d0cb151c7ca5fbc4ff88df5a87dff2369b516cc7c32cfac080029",
    info: {
      abiDefinition: [{...}, {...}, {...}, {...}],
      compilerOptions: "--combined-json bin,abi,userdoc,devdoc --add-std --optimize",
      compilerVersion: "0.4.19",
      developerDoc: {
        methods: {}
      },
      language: "Solidity",
      languageVersion: "0.4.19",
      source: "pragma solidity ^0.4.8;contract HelloWorld {    string public greeting;        function HelloWorld(string _greeting){        greeting = _greeting;    }        function setGreeting(string _greeting){        greeting = _greeting;    }        function say() constant returns (string) {        return greeting;    }}",
      userDoc: {
        methods: {}
      }
    }
  }
}

sourceCompiledから、ABI(Application Binary Interface)を取得します。ABIとは、コントラクトの外部仕様のことです。コントラクトに含まれるメソッドと引数、戻り値についての情報で、コントラクトにアクセスする際に必要な情報のひとつです

contractAbiDefinition = sourceCompiled['/tmp/geth-compile-solidity839881623:HelloWorld'].info.abiDefinition
[{
    constant: true,
    inputs: [],
    name: "say",
    outputs: [{
        name: "",
        type: "string"
    }],
    payable: false,
    stateMutability: "view",
    type: "function"
}, {
    constant: false,
    inputs: [{
        name: "_greeting",
        type: "string"
    }],
    name: "setGreeting",
    outputs: [],
    payable: false,
    stateMutability: "nonpayable",
    type: "function"
}, {
    constant: true,
    inputs: [],
    name: "greeting",
    outputs: [{
        name: "",
        type: "string"
    }],
    payable: false,
    stateMutability: "view",
    type: "function"
}, {
    inputs: [{
        name: "_greeting",
        type: "string"
    }],
    payable: false,
    stateMutability: "nonpayable",
    type: "constructor"
}]

コントラクトオブジェクトを作成

sourceCompiledContract = eth.contract(contractAbiDefinition)
{
  abi: [{
      constant: true,
      inputs: [],
      name: "say",
      outputs: [{...}],
      payable: false,
      stateMutability: "view",
      type: "function"
  }, {
      constant: false,
      inputs: [{...}],
      name: "setGreeting",
      outputs: [],
      payable: false,
      stateMutability: "nonpayable",
      type: "function"
  }, {
      constant: true,
      inputs: [],
      name: "greeting",
      outputs: [{...}],
      payable: false,
      stateMutability: "view",
      type: "function"
  }, {
      inputs: [{...}],
      payable: false,
      stateMutability: "nonpayable",
      type: "constructor"
  }],
  eth: {
    accounts: ["0x127a0614d4f606460f3cb7e05f1b9f79fdf9191b", "0x32a39ca8fd074a9c1e49b77b6613ca5287592305", "0x3b1a887c19bd3e39e926121db232f9376f2aebed", "0xe2a98f7bfc8c08fffc8fdfbabc74e80a9ccb0c6f", "0xa7732a8a03be095a4c51dd1174e1dc531b67751b", "0x215f7b161e8708280ab8d31243045b9f3c442855", "0x165df023f3371858c1bd6fe27d6724a5f9ac5ab8"],
    blockNumber: 18119,
    coinbase: "0x127a0614d4f606460f3cb7e05f1b9f79fdf9191b",
    compile: {
      lll: function(),
      serpent: function(),
      solidity: function()
    },
    defaultAccount: undefined,
    defaultBlock: "latest",
    gasPrice: 20000000000,
    hashrate: 68704,
    mining: true,
    pendingTransactions: [],
    syncing: false,
    call: function(),
    contract: function(abi),
    estimateGas: function(),
    filter: function(fil, callback),
    getAccounts: function(callback),
    getBalance: function(),
    getBlock: function(),
    getBlockNumber: function(callback),
    getBlockTransactionCount: function(),
    getBlockUncleCount: function(),
    getCode: function(),
    getCoinbase: function(callback),
    getCompilers: function(),
    getGasPrice: function(callback),
    getHashrate: function(callback),
    getMining: function(callback),
    getNatSpec: function(),
    getPendingTransactions: function(callback),
    getRawTransaction: function(),
    getRawTransactionFromBlock: function(),
    getStorageAt: function(),
    getSyncing: function(callback),
    getTransaction: function(),
    getTransactionCount: function(),
    getTransactionFromBlock: function(),
    getTransactionReceipt: function(),
    getUncle: function(),
    getWork: function(),
    iban: function(iban),
    icapNamereg: function(),
    isSyncing: function(callback),
    namereg: function(),
    resend: function(),
    sendIBANTransaction: function(),
    sendRawTransaction: function(),
    sendTransaction: function(),
    sign: function(),
    signTransaction: function(),
    submitTransaction: function(),
    submitWork: function()
  },
  at: function(address, callback),
  getData: function(),
  new: function()
}

変数に代入

 _greeting = "Hello, World 2017/12/28"
personal.unlockAccount(eth.accounts[0])

newは、ブロックチェーン上へ新しくコントラクトをデプロイするための命令です。

contract = sourceCompiledContract.new(_greeting, {from:eth.accounts[0], data: sourceCompiled['/tmp/geth-compile-solidity839881623:HelloWorld'].code, gas: '4700000'})
{
  abi: [{
      constant: true,
      inputs: [],
      name: "say",
      outputs: [{...}],
      payable: false,
      stateMutability: "view",
      type: "function"
  }, {
      constant: false,
      inputs: [{...}],
      name: "setGreeting",
      outputs: [],
      payable: false,
      stateMutability: "nonpayable",
      type: "function"
  }, {
      constant: true,
      inputs: [],
      name: "greeting",
      outputs: [{...}],
      payable: false,
      stateMutability: "view",
      type: "function"
  }, {
      inputs: [{...}],
      payable: false,
      stateMutability: "nonpayable",
      type: "constructor"
  }],
  address: undefined,
  transactionHash: "0xcc42962aef10a99eb4694f429ac48e6d9f34d22d5a85013172c0b8fe66231c17"
}

new直後はまだブロックに書き込まれていないため、address はundefinedになります。マイニングされるのを待ち、contractを確認します。

確認する

contract

アドレスが書き込まれています。

address: "0x43d59369f150532271629fbe4874cd3db353ad06"

メソッドを実行します。

contract.say.call()
"Hello, World 2017/12/28"

メソッドの実行方法には2つあります。

メソッド名 説明
sendTransaction ブロックチェーンの状態を変化させるときに使用します。ここで「状態を変化させる」とは、新しくデー タを書き込んだり、既に存在するデータを更新することを指します。これらは、ブロックチェーンのブロックを作成することで実現されるため、手数料(Gas)が発生します。ここでsendTransactionは、Etherの送金でも使用しました。Etherの送金も、残高(=状態)を変化させたと考えてください。
call ブロックチェーンからデータを取得するときに使用します。ブロックの作成は必要ありませんので、手数料は発生しません。例えば、残高の取得メソッドなどで使用します。残高は、既に存在するデータから求められますので、新たにデータを書き込む必要はありません。
personal.unlockAccount(eth.accounts[0])
contract.setGreeting.sendTransaction("Hello, Ethereum!", {from:eth. accounts[0], gas:1000000})

contract.setGreeting.sendTransaction("Hello, Ethereum!", {from:eth. accounts[0], gas:1000000})

"0xe53164fcfd0d04b429f3253b5407474574980b3dbd3f4f4f5d279459e1ac4f33"

マイニングをしばらく待つ必要があります。しばらくは、以前のままですが、途中で変わりました。

> contract.say.call()
"Hello, World 2017/12/28"
> contract.say.call()
"Hello, World 2017/12/28"
> contract.say.call()
"Hello, World 2017/12/28"
> contract.say.call()
"Hello, Ethereum!"

既存のコントラクトにアクセスしてみます。

別ターミナルを立ち上げます。

geth attach rpc:http://localhost:8545
source = 'pragma solidity ^0.4.8;contract HelloWorld {    string public greeting;        function HelloWorld(string _greeting){        greeting = _greeting;    }        function setGreeting(string _greeting){        greeting = _greeting;    }        function say() constant returns (string) {        return greeting;    }}'
sourceCompiled = eth.compile.solidity(source)
contractAbiDefinition = sourceCompiled['/tmp/geth-compile-solidity707514890:HelloWorld'].info.abiDefinition

上記のアドレスをアタッチ

contract = eth.contract(contractAbiDefinition).at("0x43d59369f150532271629fbe4874cd3db353ad06")
contract.say.call()
> contract.say.call()
"Hello, World 2017/12/28"
> contract.say.call()
"Hello, World 2017/12/28"
> contract.say.call()
"Hello, World 2017/12/28"
> contract.say.call()
"Hello, Ethereum!"
2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2