[開発][BC] review for ethereum 2

Ethereumのアカウント種類は二つ
1つがEOA(Externally Owned Account)
もう1つがContract。JavaでいうところClass

Contractには、
・内部状態を保持するストレージ(クラス変数相当)
・実行コードであるコントラクトコード(メソッド相当)=Ethereum Virtual Machine Code=EVM Code
があり、名前やトークン管理が可能

EOAからEOAへの送金も可能だが
EOAからContractへの送金も可能


EVM Codeのコンパイラの一つがSolidity
Contractの開発言語
solc=Solidityのコンパイラ

Solidity Compiler (solc) の導入

Gethにリンクされているコンパイラの確認
│ > eth.getCompilers()
│ []

まずはブツの入手
https://github.com/ethereum/browser-solidity/tree/gh-pages
「Clone or download」
任意の場所で解凍
index.htmlを実行

左上にある「New File」で新規ファイル生成
以下を入力
│ contract mortal {
│ /* Define variable owner of the type address*/
│ address owner;
│ /* this function is executed at initialization and sets the owner of the contract */
│ function mortal() { owner = msg.sender; }
│ /* Function to recover the funds on the contract */
│ function kill() { if (msg.sender == owner) suicide(owner); }
│ }
│ contract greeter is mortal {
│ /* define variable greeting of the type string */
│ string greeting;
│ /* this runs when the contract is executed */
│ function greeter(string _greeting) public {
│ greeting = _greeting;
│ }
│ /* main function */
│ function greet() constant returns (string) {
│ return greeting;
│ }
│ }

するとリアルタイムで右側にコンパイル結果が表示される

アカウント確認
| > eth.accounts[0]
| 0x7624818a50e17e65747e32e3397c455da96f9ba0
| 0x138152c1d3b695602a10040eeee147007917c635


Geth起動
C:\Geth-Win64-latest>geth init config/genesis.json
│ C:\Geth-Win64-latest>geth init config/genesis.json
│ I0914 19:09:50.503518 ethdb/database.go:82] Alloted 16MB cache and 16 file handl
│ es to C:\Users\d058171\AppData\Roaming\Ethereum\chaindata
│ I0914 19:09:50.628319 core/genesis.go:92] Genesis block already in chain. Writin
│ g canonical number
│ I0914 19:09:50.659519 cmd/geth/main.go:299] successfully wrote genesis block and
│ /or chain rule set: 3bf7629ec29c4ec5158b82e5798c95bc89562cda0a3601cb34d21f0d6a86
│ 68c0

# C:\Geth-Win64-latest>geth --networkid "10" --nodiscover --datadir "data" --mine --unlock 0x7624818a50e17e65747e32e3397c455da96f9ba0 --rpc --rpcaddr "localhost" --rpcport "8545" --rpccorsdomain "*" console 2>> "data\node.log"
│ C:\Geth-Win64-latest>geth --networkid "10" --nodiscover --datadir "data" --mine
│ --unlock 0x7624818a50e17e65747e32e3397c455da96f9ba0 --rpc --rpcaddr "localhost"
│ --rpcport "8545" --rpccorsdomain "*" console 2>> "data\node.log"
│ Unlocking account 0x7624818a50e17e65747e32e3397c455da96f9ba0 | Attempt 1/3
│ Passphrase:
│ Welcome to the Geth JavaScript console!

│ instance: Geth/v1.4.11-stable/windows/go1.6.2
│ coinbase: 0x7624818a50e17e65747e32e3397c455da96f9ba0
│ at block: 12439 (Wed, 14 Sep 2016 14:54:45 JST)
│ datadir: data
│ modules: admin:1.0 debug:1.0 eth:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txp
│ ool:1.0 web3:1.0

│ >
※ ↑の必要なかった。↓で確認できる
geth --networkid "10" --nodiscover --datadir "data" console 2>> "data\node.log"
miner.start(2)
personal.unlockAccount(eth.accounts[0], "password")

Solidity画面戻って、コンパイル結果のgreeterのWeb3 deployをコピー
│ var _greeting = /* var of type string here */ ;
│ var greeterContract = web3.eth.contract([{"constant":false,"inputs":[],"name":"kill","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"greet","outputs":[{"name":"","type":"string"}],"payable":false,"type":"function"},{"inputs":[{"name":"_greeting","type":"string"}],"type":"constructor"}]);
│ var greeter = greeterContract.new(
│ _greeting,
│ {
│ from: web3.eth.accounts[0],
│ data: '6060604052604051610339380380610339833981016040528080518201919060200150505b5b3360006...6',
│ gas: 4700000
│ }, function (e, contract){
│ console.log(e, contract);
│ if (typeof contract.address !== 'undefined') {
│ console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash);
│ }
│ })

var _greetingを任意の文字列に変換する
│ var _greeting = "hello there" ;
│ var greeterContract = web3.eth.contract([{"constant":false,"inputs":[],"name":"kill","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"greet","outputs":[{"name":"","type":"string"}],"payable":false,"type":"function"},{"inputs":[{"name":"_greeting","type":"string"}],"type":"constructor"}]);
│ var greeter = greeterContract.new(
│ _greeting,
│ {
│ from: web3.eth.accounts[0],
│ data: '6060604052604051610339380380610339833981016040528080518201919060200150505b5b3360006...6',
│ gas: 4700000
│ }, function (e, contract){
│ console.log(e, contract);
│ if (typeof contract.address !== 'undefined') {
│ console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash);
│ }
│ })


全コードをGethのコマンドに張り付ける
│ > var _greeting = "hello" ;
│ undefined
│ > {"},{"inputs":[{"name":"_greeting","type":"string"}],"type":"constructor"}]);
│ undefined
│ > var greeter = greeterContract.new(
│ ... _greeting,
│ ... {
│ ...... from: web3.eth.accounts[0],
│ ...... {6020018083116101ff57829003601f168201915b50505050509050610228565b9056',
│ ...... gas: 4700000
│ ...... }, function (e, contract){
│ ...... console.log(e, contract);
│ ...... if (typeof contract.address !== 'undefined') {
│ ......... {contract.address + ' transactionHash: ' + contract.transactionHash);
│ ......... }
│ ......
│ ...... })
│ null [object Object]
│ undefined
│ > null [object Object]

暫く待つとContractのアドレスが返される
│ Contract mined! address: 0x2a75aea2e144a2d87b6c8e137757a3dcdede73ba transactionH
│ ash: 0x6148484347211ea482ce35a09cbbf9c2162767efe7ca99d5c0713d0548e5808e
Enter押すと次のコマンドが打てるようになる
│ Contract mined! address: 0x1e1b02ed4a4e411272cf392db38a5b1ac35c11a2 transactionH
│ ash: 0x82e8a907faf1258ad0f1628d26562a3222e6541fd68265fa84f0026d143dbaf2

│ >
※ Contract Addressが異なっているのは再実行によるもの

Contractのアドレスの変わりに以下の例外になった場合
│ null [object Object]
│ undefined
│ > Error: The contract code couldn't be stored, please check your gas amount. Undefined
→入力しているデータが誤っている。(dataの情報が部分的に欠落してた)


コマンドでメソッドを呼ぶと、変換した言葉が返される
│ > greeter.greet()
│ hello there
│ >

作成したContractはアドレスとABIがあれば誰でも使用できる。
アドレスはGethへの登録時に返却される値
ABIはSolidityコンパイル画面のコンパイル結果のgreeterのInterface欄にある
※ ABI=Application Binary Interface

browser-soliditiyのInterface欄
│ [{"constant":false,"inputs":[],"name":"kill","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"greet","outputs":[{"name":"","type":"string"}],"payable":false,"type":"function"},{"inputs":[{"name":"_greeting","type":"string"}],"type":"constructor"}]

Geth画面にまずアドレス変数を定義
>var Address="0x1e1b02ed4a4e411272cf392db38a5b1ac35c11a2"
│ > var Address="0x1e1b02ed4a4e411272cf392db38a5b1ac35c11a2"
│ undefined
│ > Address
│ 0x2a75aea2e144a2d87b6c8e137757a3dcdede73ba

Gath画面にABI変数を定義
>var ABI=[{"constant":false,"inputs":[],"name":"kill","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"greet","outputs":[{"name":"","type":"string"}],"payable":false,"type":"function"},{"inputs":[{"name":"_greeting","type":"string"}],"type":"constructor"}]
別途にもう一つ変数を定義しそれらABIとAddressを紐付ける
>var greeter2=eth.contract(ABI).at(Address);
実際に呼び出し
>greeter2.greet()
│ > var Address="0x1e1b02ed4a4e411272cf392db38a5b1ac35c11a2"
│ undefined
│ > {on"},{"inputs":[{"name":"_greeting","type":"string"}],"type":"constructor"}]
│ undefined
│ > var greeter2=eth.contract(ABI).at(Address);
│ undefined
│ > greeter2.greet()
│ hello there
│ >

めでたしめでたし。


■参考
http://book.ethereum-jp.net/first_use/realtimecompiler.html

tag : ethereum Blockcahain Windows EOA Contract Geth

2016-09-17 09:38 : 開発 : コメント : 0 : トラックバック : 0 :
コメントの投稿
非公開コメント

« next  ホーム  prev »

search

ad



counter


tag cloud

category cloud