åã®èšäºã§ã Ethereumã§éçºãããã¢ããªã±ãŒã·ã§ã³ãã¬ãã¥ãŒããŸããã ããããéçºããã»ã¹ãã©ã®ããã«é²ãã§ããã®ããšããåé¡ãåé¿ããŸããã æããã«ãããã¯ãã ã¡ã«æ©èœããã³ãŒããæžãã ãã§ã¯ãããŸããã ã»ãšãã©ã®æéã¯ããã»ãŒæºåå®äºãã®ã³ãŒãã皌åç¶æ
ã«ããããã«è²»ãããªããã°ãªããŸããã å±éããã¹ãããããã°-ãããã¯ãã¹ãŠããã§ããçšåºŠè§ŠããããŠããŸããããšãã°ã次ã®åªããèšäºã§ã¯ã
1ã2ã3 ïŒãªã¹ãã¯å®å
šã§ã¯ãããŸããïŒã ãã®èšäºã§ã¯ãçãã¬ãã¥ãŒãè¡ããããããäœããç¹°ãè¿ããŸãããç§ãã¡ã«ãšã£ãŠéèŠãŸãã¯èšãããŠããªãç¹ã«çŠç¹ãåœãŠãããšããŸãã ããã«ãæè¿ããã€ãã®å€æŽãå ããããéåžžã«å€ãã®åœä»€ãéæšå¥šã«ãªããŸããã ç¶æ³ãå°ãä¿®æ£ããããšããŸãã
ããªã¥ãã®ãããžã§ã¯ã
ã¹ããŒãã³ã³ãã©ã¯ãã®ãã¹ããšå±éã«
Truffleã䜿çšããŸããäœã¬ãã«ã®äœæ¥ã®äžéšãæœè±¡åã®èåŸã«é ããŸããããã¯éåžžã«äŸ¿å©ã§ãã 説æãããŠããããŒãžã§ã³ã¯4.0.6ã§ãã ãããå¯äžã®ãã¬ãŒã ã¯ãŒã¯ã§ã¯ãããŸãã;
Embarkãš
DappleããããŸããããããã«ã€ããŠã¯äœãèšããŸãããç§ã¯ä»äºãããå¿
èŠã¯ãããŸããã§ããã ãããžã§ã¯ããåæåããã«ã¯ãã³ãã³ããå®è¡ããå¿
èŠããããŸãïŒçŸåšã®ãã©ã«ããŒã§å®è¡ããããããæåã«ãããžã§ã¯ããã©ã«ããŒãäœæããŠããã«ç§»åããŸãïŒã
$ truffle init
åºæ¬æ§é ã®ã¿ã
contracts
ã
migrations
ããã³
tests
ãã©ã«ããŒããäœæãããŸãã
contracts
ããã³
migrations
ïŒããªã¥ã-ç§»è¡ã«é¢ããŠïŒå±éããžãã¯ãæ
åœãã
Migrations
ã¹ããŒãã³ã³ãã©ã¯ãã確èªã§ããŸãã ãããŠãããžãã¯ã¯æ¬¡ã®ãããªãã®ã§ãã
migrations
ãã©ã«ããŒã«ã¹ã¯ãªããã远å ãããã³ãã¬ãŒã
1_description.js
ã
2_another_one.js
...
n_etc.js
ã«åŸã£ãŠã¹ã¯ãªããã«ååãä»ããŸãã ååã®äžã§æãéèŠãªã®ã¯ã€ã³ããã¯ã¹ã§ããããã¯å
é ã«ããããã®åŸãèªã¿ãããããããã ãã«å¿
èŠãªèª¬æã远å ã§ããŸãã ã€ã³ããã¯ã¹ã¯ãçªå·ä»ãé ã«ç§»è¡ãå®è¡ããããã«äœ¿çšãããŸãã
Migrations
ã¹ããŒãã³ã³ãã©ã¯ãã¯ãã©ã®ç§»è¡ã¹ã¯ãªãããæ¢ã«å®è¡ãããŠããããä¿åããããã«äœ¿çšãããŸãã ãã®ãããéçºããã»ã¹äžã«æ°ããã³ã³ãã©ã¯ããšæ°ããå±éããžãã¯ã远å ããå Žåã以åã®æåãã鲿ãããçŽãå¿
èŠã¯ãããŸããã å人çã«ã¯ãããã䜿çšããã代ããã«äžå®æ°ã®ç§»è¡ãè¡ãã
truffle migration --reset
ã䜿çšããŠæ¯åç·šéããŠåå®è¡ããŸãã
å¥çŽãç§»è¡ãããã³ãã¹ããã¡ã€ã«ãæåã§äœæã§ããŸãããtruffleã«ã¯ç¹å¥ãªã³ãã³ãããããŸãã
$ truffle create contract ExampleContract $ truffle create migration ExampleMigration $ truffle create test ExampleContract
é©åãªãã¡ã€ã«ãäœæããããšã確èªã§ããŸãã ãã ããã³ã³ãã³ãã¯éåžžã«åºæ¬çãªãã®ã§ãããããåããã¡ã€ã«ãæåã§äœæããå Žåãšæ¯èŒããŠããã®æ©èœã«ã¯ç¹ã«å©ç¹ã¯ãããŸããã
ãããžã§ã¯ãã§äœæ¥ãã
以åã®ããŒãžã§ã³ã§ã¯ã
truffle init
åæåã«ãããå°ããªãµã³ãã«ãäžåºŠã«äœæãããŸããïŒMetacoinããã³ConvertLibïŒã æè¿ã®ããŒãžã§ã³ã§ãããšä»ã®äŸãèŠãã«ã¯ãããªã¥ãããã¯ã¹ãšåŒã°ããæ©èœã䜿çšã§ããŸãã ããã¯ã¹ã¯ãTruffleãããžã§ã¯ããšãReactJSãªã©ã®ããŸããŸãªWebããŒã«ãšã®çžäºäœçšã®æ¬æ ŒçãªäŸãååŸããããã«äœæãããŸãã å
¬åŒããã³ã³ãã¥ããã£ã«ãã£ãŠäœæãããäž¡æ¹ã®ããã¯ã¹ã®ãªã¹ãã
次ã«ç€ºããŸãã æ°ãããããžã§ã¯ãã®ãã£ã¬ã¯ããªãäœæããŠãããã«ç§»åããŸãã æ¬¡ã«ãã³ãã³ããå®è¡ããŸãã
$ truffle unbox metacoin
å€ãããŒãžã§ã³ã§ã¯ããã©ã«ãã§
truffle init
åŸã«äœæããããããžã§ã¯ãæ§é ãååŸã
truffle init
ã ããã¯ããŠãŒã¶ãŒãããŠãŒã¶ãŒã«éä¿¡ã§ããConvertLibã©ã€ãã©ãªã䜿çšããŠåºå®çºæ¿ã¬ãŒãã§ç©ºäžæ®é«ãç£èŠã§ãããåºæ¬çãªMetacoinããŒã¯ã³ã®äŸã§ãã ã¹ããŒãã³ã³ãã©ã¯ããšã©ã€ãã©ãªãäœæããã³äœ¿çšããæ¹æ³ãããã§ç€ºãããã®ã«å ããŠãJavaScriptããã³Solidityã®ãã¹ãã®äŸããããŸãïŒãã¹ãã®èšè¿°ã«é¢ãã詳现ã¯
ãã¡ããã芧ãã ãããTruffleã®å€ãããŒãžã§ã³ã¯ããã§æ€èšãããŠããŸãïŒã ãã®ãããžã§ã¯ãããã¹ãã¢ãŒãã§ãã«ãããã³ãã¹ãããæ¹æ³ãç°¡åã«èŠãŠã¿ãŸãããã ãŸããéçºã³ã³ãœãŒã«ãå®è¡ããŸãã
$ truffle develop
åæ§ã®ããã¹ããåç
§ããŠãã ããïŒ
Truffle Develop started at http://localhost:9545/ Accounts: (0) 0x627306090abab3a6e1400e9345bc60c78a8bef57 (1) 0xf17f52151ebef6c7334fad080c5704d77216b732 (2) 0xc5fdf4076b8f3a5357c5e395ab970b5b54098fef (3) 0x821aea9a577a9b44299b9c15c88cf3087f3b5544 (4) 0x0d1d4e623d10f9fba5db95830f7d3839406c6af2 (5) 0x2932b7a2355d6fecc4b5c0b6bd44cc31df247a2e (6) 0x2191ef87e392377ec08e7c08eb105ef5448eced5 (7) 0x0f4f2ac550a1b4e2280d04c21cea7ebd822934b5 (8) 0x6330a553fc93768f612722bb8c2ec78ac90b3bbc (9) 0x5aeda56215b167893e80b4fe645ba6d5bab767de Mnemonic: candy maple cake sugar pudding cream honey rich smooth crumble sweet treat truffle(develop)>
ãã®ããŒã ã¯äœãããŸããïŒ ãã¹ãç°å¢ãäžããã³ã³ãœãŒã«ããã¢ã¯ã»ã¹ã§ããããã«ããŸãã ãã¹ãç°å¢ã¯ãTestRPCãšåŒã°ããå€ãããã¥ã¢ã«ã§èŠãããšãã§ãããã®ã§ãã å®éãããã¯ããã§ããTruffleããŒã ã ãããããå¶åŸ¡ãã
Ganacheãšååã倿ŽããŸããã ãã ããããã«ã€ããŠã¯åŸã§èª¬æããŸãããä»ã®ãšããã¯ã³ã³ãœãŒã«ã«ç§»ããŸãããã ã³ã³ãã€ã«ãç§»è¡ããã¹ãçšã®ã³ãã³ãã®ãã«ãµã€ã¯ã«ãå®è¡ããŠã¿ãŸãããã
truffle(develop)> compile
çµæ Compiling ./contracts/ConvertLib.sol... Compiling ./contracts/MetaCoin.sol... Compiling ./contracts/Migrations.sol... Writing artifacts to ./build/contracts
truffle(develop)> migrate
çµæ Using network 'develop'. Running migration: 1_initial_migration.js Deploying Migrations... ... 0x29619f8ba9b9e001bef885c8ca2fbee45beab738adc41c7f9e2e8273fbc67e9f Migrations: 0x8cdaf0cd259887258bc13a92c0a6da92698644c0 Saving successful migration to network... ... 0xd7bc86d31bee32fa3988f1c1eabce403a1b5d570340a3a9cdba53a472ee8c956 Saving artifacts... Running migration: 2_deploy_contracts.js Deploying ConvertLib... ... 0x02318651545ac96670af626ef7795cb928d7504afc3f856258058ce579d47fe6 ConvertLib: 0x345ca3e014aaf5dca488057592ee47305d9b3e10 Linking ConvertLib to MetaCoin Deploying MetaCoin... ... 0x486c572bbb2df30bb166f5507423d394807b5b92041860968a7d5eb162e42e48 MetaCoin: 0xf25186b5081ff5ce73482ad761db0eb0d25abfbf Saving successful migration to network... ... 0x059cf1bbc372b9348ce487de910358801bbbd1c89182853439bec0afaee6c7db Saving artifacts...
truffle(develop)> test
çµæ Using network 'develop'. Compiling ./contracts/ConvertLib.sol... Compiling ./contracts/MetaCoin.sol... Compiling ./test/TestMetacoin.sol... Compiling truffle/Assert.sol... Compiling truffle/DeployedAddresses.sol... TestMetacoin â testInitialBalanceUsingDeployedContract (62ms) â testInitialBalanceWithNewMetaCoin (47ms) Contract: MetaCoin â should put 10000 MetaCoin in the first account â should call a function that depends on a linked library (54ms) â should send coin correctly (117ms) 5 passing (796ms)
ããšãã°ã次ã®ããã«ãç¡å¹ãªã³ã³ãã©ã¯ãã®ã¡ãœãããæåã§åŒã³åºãããšãã§ããŸãã
truffle(develop)> var metaCoin truffle(develop)> MetaCoin.deployed().then( function(instance) { metaCoin = instance } ); truffle(develop)> metaCoin.getBalance(web3.eth.coinbase) BigNumber { s: 1, e: 4, c: [ 10000 ] } truffle(develop)> _.toNumber() 10000 truffle(develop)> metaCoin.sendCoin( web3.eth.accounts[2], 3000 ) { tx: '0x9f59085a9f22c0bd691b890370bcffd7eedce1327a3bb525a2de3edf9db0d279', receipt: { transactionHash: '0x9f59085a9f22c0bd691b890370bcffd7eedce1327a3bb525a2de3edf9db0d279', transactionIndex: 0, blockHash: '0x24e8913b6f707bb5e5acbaa054fef9dabd548a561dc988763209f0aeed9a57b5', blockNumber: 12, gasUsed: 51024, cumulativeGasUsed: 51024, contractAddress: null, logs: [ [Object] ] }, logs: [ { logIndex: 0, transactionIndex: 0, transactionHash: '0x9f59085a9f22c0bd691b890370bcffd7eedce1327a3bb525a2de3edf9db0d279', blockHash: '0x24e8913b6f707bb5e5acbaa054fef9dabd548a561dc988763209f0aeed9a57b5', blockNumber: 12, address: '0xf25186b5081ff5ce73482ad761db0eb0d25abfbf', type: 'mined', event: 'Transfer', args: [Object] } ] } truffle(develop)> metaCoin.getBalance(web3.eth.coinbase) BigNumber { s: 1, e: 3, c: [ 7000 ] } truffle(develop)> _.toNumber() 7000
ã芧ã®ãšããããã¹ãŠãå³åº§ã«è¡ããã倿Žã远跡ã§ããŸããã¡ã€ã³ã¢ãã¬ã¹ããå¥ã®ã¢ãã¬ã¹ã«3000ãéä¿¡ãããããæ®é«ãæžå°ããŠããããšãããããŸãã æ¬¡ã®ã³ãã³ãã§ã³ã³ãœãŒã«ãçµäºããŸãã
truffle(develop)> .exit
ããŒããžã®æ¥ç¶
ããªã¥ãã®éçºã¯ãç¬èªã®ãã¹ãããŒããåããã¢ãŒãã§ãã å®éã®ãããã¯ãŒã¯ãŸãã¯ãã¹ããããã«æ¥ç¶ããã«ã¯ã
truffle console
ã³ãã³ãã䜿çšããŸããããã¯ã
develop
ã«å®å
šã«äŒŒãŠããŸããããã¹ãç°å¢ãäžããŸããã ãããå®èšŒããããã«ã
geth
ãå®è¡ããå¿
èŠã¯ãããŸãããããšãã°ã
geth
ã䜿çšã§ããŸãã ã³ãã³ããå®è¡ããŸãïŒ
$ ganache-cli
GUIããŒãžã§ã³ããããŸãã åºæ¬çãªéãã¯ãããŸãããããã®ããŒãžã§ã³ã§ã¯ããã¹ãŠã®æ
å ±ãã€ãã³ããæ®é«ãããã«èŠãããšãã§ããŸãã ç¶æ³ã«ãã£ãŠã¯éåžžã«äŸ¿å©ã§ãã ãããã®ããŒãžã§ã³ã®ããããã䜿çšã§ããŸãã
ãã ãã
truffle unbox metacoin
ãäœæããã°ããã§ãæ§æãã¡ã€ã«ããŸã 倿ŽããŠããªãå Žåã¯ãæ¥ç¶ã§ããŸãã
$ truffle console No network available. Use `truffle develop` or add network to truffle.js config.
ãããã£ãŠã次ã
truffle.js
远å ããŸãã
module.exports = { networks: { development: { host: "localhost", port: 8545, network_id: "*" } } };
truffle-config.js
ã確èª
truffle-config.js
ãŸãã ããã¯åãã§ãããWindowsã®å Žåã§ãã ã·ã¹ãã ã®äœåãªãã¡ã€ã«ã¯åé€ã§ããŸãã
ãã®èšå®ã«ãããããªã¥ãã¯ããŒã«ã«ãã¹ãã§å©çšå¯èœãªä»»æã®ãããã¯ãŒã¯ã«æ¥ç¶ã§ããŸãïŒ8545ã ãããã¯ãgethããã³ganache-cliã®ããã©ã«ãå€ã§ãã Ganacheã®GUIããŒãžã§ã³ã䜿çšããŠããå Žåã¯ãèšå®ã«ç§»åããå¿
èŠã«å¿ããŠããŒãã倿ŽããŠåèµ·åããŸãïŒãä¿åããŠåèµ·åããã¿ã³ïŒã
ããŽã®ä»ãããŠã£ã³ããŠã§ç«ã¡åŸçããŠããå Žåã¯ãããããåãããŒããgethãganache-cli / testrpcããŸãã¯ä»ã®äœãã§æ¢ã«äœããå®è¡ããŠãã
ããã§ãæ¥ç¶ããŠã³ãã³ããå®è¡ã§ããŸãã
$ truffle console
ãããŠãããªãã¯äŸãã°ããããšããããšãã§ããŸãïŒ
truffle(development)> migrate --reset
GUIããŒãžã§ã³ã§ã¯ãå±éå
ã®ã¢ã«ãŠã³ãã®æ®é«ã®å€åãããã«ç¢ºèªã§ããŸãã[ãããã¯]ã¿ãã«ç§»åãããšãç¬é¡ã®ãããã¯ãšããããã¯å
ã®ãã©ã³ã¶ã¯ã·ã§ã³ã«è²»ããããã¬ã¹éã衚瀺ãããŸãã ãããããã¯ãªãã¯ãããšãããã«è©³çŽ°ãªæ
å ±ãååŸã§ããŸãã åæ§ã«ã[ãã©ã³ã¶ã¯ã·ã§ã³]ã¿ãã«ã¯éå»ã®ãã¹ãŠã®ãã©ã³ã¶ã¯ã·ã§ã³ã衚瀺ãããŸãã
å€ãã®ã¹ã¯ãªãŒã³ã·ã§ãã ã³ã³ãœãŒã«ããŒãžã§ã³ã«ã¯åãæ
å ±ããããŸããããã°ãŠã©ãŒã«ã®åœ¢åŒã«ãªããŸãã
å±éãã net_version eth_accounts eth_accounts net_version net_version eth_sendTransaction Transaction: 0x29619f8ba9b9e001bef885c8ca2fbee45beab738adc41c7f9e2e8273fbc67e9f Contract created: 0x922194d35a507e5905fa4f2c9e7172ee8535272a Gas usage: 269607 Block Number: 1 Block Time: Mon Feb 05 2018 10:28:17 GMT+0300 (MSK) eth_newBlockFilter eth_getFilterChanges eth_getTransactionReceipt eth_getCode eth_uninstallFilter eth_sendTransaction Transaction: 0xfafc4352cc1dde57e46954d7ebd3a59232599081a253dd8705847a380ae5b06b Gas usage: 41981 Block Number: 2 Block Time: Mon Feb 05 2018 10:28:17 GMT+0300 (MSK) eth_getTransactionReceipt eth_accounts net_version net_version eth_sendTransaction
ããªãããã䟿å©ã ãšæããã®ã䜿ã£ãŠãã ããã
ã¡ãªã¿ã«ãåããããã¯ã«é¢ããä»ã®æç€ºãèªãã å Žåãããããã³ã³ãã€ã«ãšãããã€ã®ããã«ã³ã³ãœãŒã«ãåŒã³åºãå¿
èŠã¯ãªãããšãæ¢ã«ç¥ã£ãŠããã§ããããããšãã°ãåã«åŒã³åºãããšãã§ããŸã
truffle migrate --reset
ãããŠãããã¯äžèšã§è¡ã£ãããšã®å®å
šãªé¡äŒŒç©ã«ãªããŸãã åãååãä»ã®ãã¹ãŠã®ããªã¥ãããŒã ã«ãé©çšãããŸãã ã³ãã³ãã®å
šãªã¹ãã¯
ãã¡ã ã
ããã±ãŒãž
ã³ã¢æ©èœãå®è¡ã§ããèšèªã¯ãããŸããã èªè»¢è»ã®çºæã¯éçç£çã§å±éºã§ãããä»ã®äººã®ãéãå±éºã«ãããã¹ããŒããªå¥çŽã§ã¯ãããã¯ç¹ã«éèŠã§ãã ãããã£ãŠããã§ã«ãã¹ãæžã¿ã®è¿œå æ©èœãã©ãã§å
¥æããããšããçåãçããŸãã Truffleã«ã¯ãã®ããã®ããã±ãŒãžã·ã¹ãã ãããã2ã€ã®ã€ã³ã¹ããŒã«ãªãã·ã§ã³ïŒéåžžã®ã³ããŒãšè²Œãä»ããé€ãïŒã§äœ¿çšã§ããŸããnpmã䜿çšããæ¹æ³ãšethpmã䜿çšããæ¹æ³ã§ãã
ããã«å
ç«ã¡ãã¡ã¿ã³ã€ã³ã®äŸã§ãæãåçŽãªããŒã¯ã³ãèŠãŸããã ããŒã¯ã³ã¯éåžžã«é »ç¹ã«äœ¿çšãããŸããæå·ããã£ã§ãããå
ã®æšæºã§ã¯ãããŸãããæ¬è³ªçã«ããŒã¯ã³ã§ãã çŸåšãããŒã¯ã³ã®äž»ãªæšæºã¯
ERC20ã§ãã æšæºã«æºæ ããã«ã¯ãããŒã¯ã³ã¯ããŠã©ã¬ããã亀æãªã©ã§æ®éçã§å®å
šãªäœ¿çšãæäŸã§ããäžé£ã®æ©èœãå®è£
ããå¿
èŠããããŸãã
ããã§ã¯
ãOpenZeppelinã®
zeppelin-solidityããã±ãŒãžãéåžžã«äŸ¿å©ã§ããã¹ããŒãã³ã³ãã©ã¯ãã§ãã䜿çšããããã¿ãŒã³ã®ã©ã€ãã©ãªã»ããã§ãã ããšãã°ã
ãã®èšäºã§ã¯ãæ¢ã«ãã®ããã±ãŒãžã®äœ¿çšã«ã€ããŠèª¬æããŠããŸãã 䜿çšã§ã¯ãªããã€ã³ã¹ããŒã«ããã³æ¥ç¶æ¹æ³ãæ€èšããŠãã ããã æå§ãã«ããããžã§ã¯ãgithubã®æç€ºã§èª¬æãããŠãããã®ã ããªã¥ããããžã§ã¯ãã®ã«ãŒãã§ãæ¬¡ã®æäœãè¡ããŸãã
$ npm init -y $ npm install -E zeppelin-solidity
次ã«
node_modules
ãã©ã«ããŒã§
zeppelin-solidity
ãååŸããŸãããããããã¹ããŒãã³ã³ãã©ã¯ãã®å¿
èŠãªãã¡ã€ã«ïŒææå¯èœãªã©ïŒã次ã®è¡ã§æ¥ç¶ã§ããŸãã
import 'zeppelin-solidity/contracts/ownership/Ownable.sol';
ããããEthereumã®ããã±ãŒãžå°çšã«èšèšãããããã±ãŒãžãã€ã³ã¹ããŒã«ããå¥ã®æ¹æ³ããããŸãïŒEthPMã ãã±ããã¯IPFSã«ä¿åãããŸãã ããã±ãŒãžã®ãªã¹ãã¯
ãã¡ãããå
¥æã§ã
ãŸã ã ããªã¥ãã«çµ±åãããŠãããåãzeppelin-solidityãèšå®ããã«ã¯ã次ãå®è¡ã§ããŸãã
$ truffle install zeppelin
installed_contractsãã©ã«ããŒã远å ããã
node_modules
ãã©ã«ããŒãããšåãæ¹æ³ã§ãã®å
容ã
node_modules
ãŸãã
import 'zeppelin/contracts/ownership/Ownable.sol';
ããããäœããã®æ¹æ³ã§ã€ã³ã¹ããŒã«ãããŠããããŒãžã§ã³ãæ¯èŒãããšãç°ãªãããšãããããŸãã ãããŠãå°ãªããšãçŸæç¹ã§ã¯ãnpmããŒãžã§ã³ã®æ¹ãæ°ããïŒEthPmã§1.6.0ãš1.3.0ãæžããŠããæç¹ïŒã ãããã£ãŠãã€ããªãã®ãŒçã«ã¯ãEthPMã¯ããè峿·±ããã®ã§ãããçŸæç¹ã§ã¯npmã䜿çšããŠããã±ãŒãžãã€ã³ã¹ããŒã«ããæ¹ãè¯ãã§ããã
ãããã°
éåžžãã¹ããŒãã³ã³ãã©ã¯ãã®å®è¡äžã«ãšã©ãŒãçºçãããšãã¡ãã»ãŒãžã¯éåžžã«æçã§ã¯ãªããªããŸãã ããšãã°ãæå³çãªééãã§å¥çŽãããŸãã
$ mkdir FaultyContract && cd FaultyContract $ truffle init $ truffle create contract FaultyContract $ truffle create migration deploy
contracts / FaultyContract.solãã¡ã€ã«ã§ãæ¬ èœã³ãŒãã远å ããŸãã
pragma solidity ^0.4.4; contract FaultyContract { int public result; function divideXbyY( int x, int y ) public { y -= y; result = x/y; } }
ããã§ãããããã«ã0ã«ããé€ç®ã¯é¿ããããŸããã
ãã¡ã€ã«ã®
migration/xxxx_deploy.js
ïŒxxxxã¯çæãããIDã§ãããç°ãªãå ŽåããããŸãïŒã«ããããã€ã¡ã³ãã®æ¬ èœã³ãŒãã远å ããŸãã
var FaultyContract = artifacts.require("./FaultyContract.sol"); module.exports = function( deployer ) { deployer.deploy( FaultyContract ); }
éçºã³ã³ãœãŒã«ãéããŠãå¥çŽãã³ã³ãã€ã«ããŠä¿è·ããŸããã
$ truffle develop truffle(develop)> migrate
ã³ã³ãã©ã¯ããååŸããåé¡é¢æ°ãåŒã³åºããŸãã
truffle(develop)> var faultyContract; truffle(develop)> FaultyContract.deployed().then( function(instance) { faultyContract = instance } ); truffle(develop)> faultyContract.divideXbyY(16, 4); Error: VM Exception while processing transaction: invalid opcode at Object.InvalidResponse (/usr/lib/node_modules/truffle/build/cli.bundled.js:43303:16) at /usr/lib/node_modules/truffle/build/cli.bundled.js:331156:36 at /usr/lib/node_modules/truffle/build/cli.bundled.js:314196:9 at XMLHttpRequest.request.onreadystatechange (/usr/lib/node_modules/truffle/build/cli.bundled.js:329855:7) at XMLHttpRequestEventTarget.dispatchEvent (/usr/lib/node_modules/truffle/build/cli.bundled.js:70159:18) at XMLHttpRequest._setReadyState (/usr/lib/node_modules/truffle/build/cli.bundled.js:70449:12) at XMLHttpRequest._onHttpResponseEnd (/usr/lib/node_modules/truffle/build/cli.bundled.js:70604:12)
ã芧ã®ãšãããããã¯ããŸãæçã§ã¯ãªãããšã©ãŒã®å Žæãš
invalid opcode
æå³ãããããŸããã TruffleããŒãžã§ã³4以éã§ã¯ã
debug
ã³ãã³ããå©çšå¯èœïŒãããŸã§ã®ããŒã¿çïŒã§ããããã©ã³ã¶ã¯ã·ã§ã³ãè¡ããšã«åå®è¡ã§ããŸãã ãããããã®ããã«ã¯ãã©ã³ã¶ã¯ã·ã§ã³ã®ããã·ã¥ãååŸããå¿
èŠããããŸããããšã©ãŒã§ã¯ããã«ãããããŸããã ããã·ã¥ã衚瀺
truffle develop
ã¯ã
--log
ãã©ã°ãæå®ããŠ
truffle develop
å¥ã®ã€ã³ã¹ã¿ã³ã¹ãå®è¡ããŸãã
$ truffle develop --log
ãã®ã³ãã³ãã䜿çšãããšãã¡ã€ã³ã®éçºã³ã³ãœãŒã«ã§äœãèµ·ãã£ãŠãããã®ãã°ã衚瀺ã§ããŸãããŸããããã§ãã©ã³ã¶ã¯ã·ã§ã³ã®ããã·ã¥ãèŠã€ããããšãã§ããŸãã 颿°ãå床å®è¡ããŸã
truffle(develop)> faultyContract.divideXbyY(16, 4);
ãã°ã®ãããŠã£ã³ããŠã«ã¯ã次ã®ãããªãã®ããããŸãã
develop:testrpc eth_sendTransaction +0ms develop:testrpc +27ms develop:testrpc Transaction: 0x21073e12e7c8fb785347d7bd5d974d4954379dcace7b53d452c03b39ca007b9e +1ms develop:testrpc Gas usage: 6721975 +0ms develop:testrpc Block Number: 6 +0ms develop:testrpc Block Time: Tue Feb 06 2018 10:32:27 GMT+0300 (MSK) +0ms develop:testrpc Runtime Error: invalid opcode +0ms develop:testrpc +0ms
ãã©ã³ã¶ã¯ã·ã§ã³ã®ããã·ã¥ãååŸããŠãdebugã³ãã³ãã«æž¡ããŸãã
truffle(develop)> debug 0x21073e12e7c8fb785347d7bd5d974d4954379dcace7b53d452c03b39ca007b9e
ããã«ã³ãã³ããå
¥åããå¿
èŠããããŸãã ãšã©ãŒã®å°ãªããšãããã€ãã®è¡ãçè§£ããã«ã¯ã
n
ïŒæ¬¡ã®ã¹ãããïŒã³ãã³ãã䜿çšã§ããŸãã
debug(develop:0x21073e12...)> n FaultyContract.sol | 0x345ca3e014aaf5dca488057592ee47305d9b3e10: 8: int public result; 9: 10: function divideXbyY( int x, int y ) public { ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ debug(develop:0x21073e12...)>
åã¹ãããã¯æ°è¡ã®ã³ãŒãã衚瀺ããçŸåšå®è¡ãããŠããéšåã匷調ããŸãã éåžžã«äœãã¬ãã«ã«ç§»åããŠãåãªãã³ãŒãïŒEthereumä»®æ³ãã·ã³ã³ãã³ãïŒãå®è¡ããã¹ã¿ãã¯ã®ç¶æ
ã調ã¹ãããšãã§ããŸãã ãã1ã€ã®ã¹ããããèžã¿ãã¹ã¿ãã¯ã®ç¶æ
ãæšæž¬ããŠã¿ãŸãããã
debug(develop:0x21073e12...)> FaultyContract.sol | 0x345ca3e014aaf5dca488057592ee47305d9b3e10: 9: 10: function divideXbyY( int x, int y ) public { 11: y -= y; ^ debug(develop:0x21073e12...)> p FaultyContract.sol | 0x345ca3e014aaf5dca488057592ee47305d9b3e10: (55) DUP1 00000000000000000000000000000000000000000000000000000000c6329782 000000000000000000000000000000000000000000000000000000000000009b 0000000000000000000000000000000000000000000000000000000000000010 0000000000000000000000000000000000000000000000000000000000000004 (top)
xãšyã16ã4ãã¹ã¿ãã¯ã®æåŸã§ããããšãããããŸãããããã¯ç¢ºãã«éåžžã«äŸ¿å©ãªæ¹æ³ã§ã¯ãªãããªãã³ãŒããšããããã€ãŒãµãªã¢ã ä»®æ³ãã·ã³ã§å®è¡ãããæ¹æ³ã«å¯ŸåŠããå¿
èŠããããŸãã èå³ãããå Žå-
é»è²ã®çŽ ïŒH.2ãåœä»€ã»ããïŒãèŠãããšãã§ããŸãã ããããç§ãã¡ã®ã¿ã¹ã¯ã¯ããšã©ãŒã®ããè¡ãèŠã€ããããšã§ãã
next step
ãããªçµæãåŸããããŸã§ã
next step
ãå®è¡ãç¶ããŸãã
10: function divideXbyY( int x, int y ) public { 11: y -= y; 12: result = x/y; ^^^ debug(develop:0x21073e12...)> Transaction halted with a RUNTIME ERROR. This is likely due to an intentional halting expression, like assert(), require() or revert(). It can also be due to out-of-gas exceptions. Please inspect your transaction parameters and contract code to determine the meaning of this error. truffle(develop)>
ããã§ã¯ãå°ãªããšããéšéã®ã©ããã§ãšã©ãŒãçºçããããšãããããŸãã ãããŠãçè§£ããã°ã¹ã¿ãã¯ãšæé ãèŠãããšãã§ããŸãã æ®å¿µãªãããããã¯ãããã°ã«é¢ããŠããªã¥ããæäŸãããã¹ãŠã§ãã ãŸããå°ãªããšãäœãã
ãã®ç¹ã«é¢ããŠãåäžã®ã³ã³ãã©ã¯ããšåçŽãªæ¥ç¶ã«ã€ããŠã¯ã
Remix IDEã«ã¢ããã€ã¹ããããšãã§ããŸãïŒ
ãã®èšäºã§ã¯ ãããšãã°äœæè
ãå±éã«äœ¿çšããŸãïŒããã¹ãŠã®ã¹ãããã§å€æ°ã®å€ã確èªã§ããã»ãŒå®å
šãªãããã°ããããŸãã ã€ã³ã¿ãŒãã§ãŒã¹ã¯çŽæçã§ãããã§ã«èª¬æããäŸãã©ã®ããã«ãããã°ã§ãããã確èªããŠãã ããã
以äžã®ã³ã³ãœãŒã«ã§ãšã©ãŒã衚瀺ããããã[ãããã°]ãã¯ãªãã¯ããŸãã

ãããŠãååŸã«ã¹ã¯ããŒã«ããŠã人éã®åœ¢ã§å€æ°ã®å€ãèŠãããšãã§ããŸãã
ãªã¢ãŒãããŒãInfura
ååã®èšäºã§ã¯ãããŒã«ã«ã®åæãããã€ãŒãµãªã¢ã ã¯ã©ã€ã¢ã³ãã䜿çšããã«ãããã¯ãã§ãŒã³ã«æ¥ç¶ã§ããMetamaskãã©ã°ã€ã³ã«ã€ããŠæ€èšããŸããã ããã¯
InfuraãµãŒãã¹ã®ãããã§ãã InfuraããŒãã«ã¢ã¯ã»ã¹ããããªã¥ããä»ããŠãããã«æ¥ç¶ããããšãã§ããŸãã ãããè¡ãã«ã¯ããŸãã
ãŠã§ããµã€ãã«
ç»é²ããå¿
èŠããããŸããæçŽã§ãã¢ã¯ã»ã¹çšã®å人ããŒã¯ã³ãå«ããªã³ã¯ãåãåããŸãã ããŒã«ã«ããŒããªãã§Ropstenã«Metacoinã®äŸãå±éããŠã¿ãŸãããã
éåžžã©ãããã¹ããããžã§ã¯ããäœæããŸãã
$ mkdir metacoin && cd metacoin $ truffle unbox metacoin
次ã«ãTruffleããã©ã³ã¶ã¯ã·ã§ã³ã«çœ²åã§ãã远å ã®ããã±ãŒãž
HDWalletProviderãå¿
èŠã§ãã
$ npm init $ npm install $ npm install truffle-hdwallet-provider
次ã®ã³ãŒãã䜿çšããŠãããªã¥ãèšå®ã«ãããã€ããŒã远å ããŸãã
var HDWalletProvider = require("truffle-hdwallet-provider"); var mnemonic = "correct horse battery staple correct horse battery staple correct horse battery staple" module.exports = { networks: { development: { host: "localhost", port: 8545, network_id: "*" }, ropsten: { provider: function() { return new HDWalletProvider(mnemonic, "https://ropsten.infura.io/< >") }, network_id: 3, gas: 4000000, gasPrice: 21000000000 } } };
å°ãªããšãããã©ã«ãå€ãé©åããªãã£ããããgasãšgasPriceãèšå®ããå¿
èŠããããŸããã æçŽããããŒã¯ã³ãæ¿å
¥ããããšãå¿ããªãã§ãã ããããŸãã12ã®ç°ãªãïŒäŸã®ããã«ã§ã¯ãªãïŒåèªããç¬èªã®ããŒã¢ããã¯ãèãåºãããšãå¿ããªãã§ãã ããã ã ããšãã°ããã®èšäºã§ããŒã¢ããã¯ã䜿çšããå Žåã¯ãããã«éä¿¡ãããšãŒãã«ïŒ0.3ïŒã䜿çšã§ããŸãïŒä»ã®äººã䜿çšããªãå ŽåïŒã ãã®èšå®ã«
development
ãæ®ãããŠããŸãã--networkãã©ã°ã®åŸã«å¯Ÿå¿ããååã§truffleãå®è¡ããããšã«ãããããã2ã€ã®ãããã¯ãŒã¯ããéžæã§ããŸãã
$ truffle console --network ropsten
migrate
ãåŒã³åºãåã«ãçæãããã¢ã«ãŠã³ãã®æ®é«ãè£å
ããå¿
èŠããããŸãã ã³ãã³ãã®ã¢ãã¬ã¹ãšãã©ã³ã¹ã確èªããŸãã
truffle(ropsten)> web3.eth.getAccounts( function(e,r) { console.log(r[0]); } ); undefined 0x0bb542704819b5e6a28deb2b73245be57ce0e78b truffle(ropsten)> web3.eth.getBalance('0x0bb542704819b5e6a28deb2b73245be57ce0e78b', function(e, r) { console.log( web3.fromWei( r.toNumber() ) ); }) undefined 0
RopstenãããŒããã£ã¹ããã¢ã«ãŠã³ãã«éä¿¡ããŠãå±éã®æéãæ¯æãããšãã§ããŸãã å°çãããïŒåã®ã³ãã³ãã§ç¢ºèªã§ããŸãïŒã
migrate
ã詊ãããšãã§ããŸãïŒ
truffle(ropsten)> migrate
çµæã¯æ¬¡ã®ããã«ãªããŸãã
Compiling ./contracts/ConvertLib.sol... Compiling ./contracts/MetaCoin.sol... Compiling ./contracts/Migrations.sol... Writing artifacts to ./build/contracts Using network 'ropsten'. Running migration: 1_initial_migration.js Deploying Migrations... ... 0x93cf7dbde8c362534dc912926fc4d7df54c9c1f5e0a7dcfd964a0177b42bc7be Migrations: 0x02519d13f61bdcad838d938611e6722c3d1f8034 Saving successful migration to network... ... 0xec501a78cc11c723ab60186167765aa7c422177153cd72a976e66441db2b5b95 Saving artifacts... Running migration: 2_deploy_contracts.js Deploying ConvertLib... ... 0xf172d9a9ff9f1fdfdfabc816d89f5a5e710ba26e3a2ad9e1661c9dea56564f04 ConvertLib: 0xd04bffb73bf546985938a596565141d3a3bf7f0d Linking ConvertLib to MetaCoin Deploying MetaCoin... ... 0x4d9814f1d9a959e83828bf26319dd91d73be977395d88e9e8239bb4c4ed5b0eb MetaCoin: 0x20fd16643d857ce544a91ae4c80385af99dad196 Saving successful migration to network... ... 0x0dff866460d24d56d94dcf5f833aa4fa8ae289cb708ff5c9012ce21447575ce8 Saving artifacts... truffle(ropsten)>
ãã©ã³ã¶ã¯ã·ã§ã³ã®ããã·ã¥ã衚瀺ãããŸããetherscan.ioãä»ããŠå®éã«Ropstenã«å°éããããšã確èªã§ããŸãïŒããšãã°ã
ropsten.etherscan.io / tx / 0x93cf7dbde8c362534dc912926fc4d7df54c9c1f5e0a7dcfd964a0177b42bc7be ïŒ
次ã¯ïŒ
ãã®èšäºããäœãæ°ããããšãåŠãã ããå°ãªããšãç¥èãæŽæ°ãããããšãé¡ã£ãŠããŸãã
次ã®èšäºã«ã€ããŠã¯ãå®è·µã瀺ããŠããããã«ãOraclizeãšIPFSãä»ããŠå€éšãšéä¿¡ããããšãªããçã«æçšãªãããžã§ã¯ããäœæããããšã¯å°é£ã§ãã ããã«ã€ããŠæžãäºå®ã§ãã
ã€ãŒãµãªã¢ã ã§ã®éçºã®ã€ããŒãžã§ã³ïŒ
ããŒã1ïŒã¯ããã«ããŒã2ïŒWeb3.jsãšã¬ã¹ããŒã3ïŒãŠãŒã¶ãŒã¢ããªã±ãŒã·ã§ã³