Truffle v5を利用して INFURA のROPSTEN Testnet に簡単なコントラクトをデプロイしてみます。
下記リンクの記事では Truffle v4.1.8 で説明しています。v5 においては仕様が変更されています。コントラクトをデプロイするための基本は変わりませんが、本記事では変更された設定ファイルやINFURAの画面などの説明をしていきます。
TruffleでINFURAにコントラクトをデプロイする[web3.js]
Truffle v5 のインストールや説明は関連ページをご覧下さい。
バージョンを確認します。
1 2 3 4 5 |
$ truffle version Truffle v5.0.31 (core: 5.0.31) Solidity v0.5.0 (solc-js) Node v12.6.0 Web3.js v1.2.1 |
適当なプロジェクト(ディレクトリ)を作成し、初期化します。
1 2 3 |
$ mkdir HelloProject $ cd HelloProject/ $ truffle init |
contractsディレクトリ内にHelloWorld.solを作成します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
pragma solidity >=0.4.25 <0.6.0; contract HelloWorld { string word; constructor(string memory _word) public { word = _word; } function getWord() public view returns(string memory) { return word; } function changeWord(string memory _word) public { word = _word; } } |
migrationsディレクトリ内に下記のマイグレーションファイル(2_deploy_contracts.js)を作成します。コントラクト生成時のコンストラクタの引数として「こんにちわ」を渡しています。
1 2 3 4 5 6 |
const HelloWorld = artifacts.require("HelloWorld"); module.exports = (deployer) => { const word = "こんにちわ"; deployer.deploy(HelloWorld, word, { gas: 2000000 }); }; |
truffle-config.js の設定
truffle-config.jsにROPSTEN Testnetの設定をします。
まず下記部分を有効化します。
1 2 3 4 5 |
const HDWalletProvider = require('truffle-hdwallet-provider'); const infuraKey = "◯◯◯"; const fs = require('fs'); const mnemonic = fs.readFileSync(".secret").toString().trim(); |
1行目
INFURAはユーザーに対してセキュリティの関係上、トランザクションの署名に必要となる秘密鍵を提供していません。しかし、このHDWalletProviderを利用することによって署名を行うことができます。インストールについては下記の「コントラクトのコンパイルとマイグレーション」で説明しています。
2行目
infuraKey には、INFURAのキー(ENDPOINT)を取得して設定する必要があります(下記で説明)。
4行目
.secret ファイルを作成し、そこに12個の英単語であるmnemonic(ニーモニック)文字列を記述する必要があります。そのファイルを読み取っています。
1 |
$ vi .secret |
INFURA自体の説明およびmnemonicを取得するMetaMask等についてはあらためて下記のページをご覧下さい。
TruffleでINFURAにコントラクトをデプロイする[web3.js]
次にropstenの項目を有効化します。
1 2 3 4 5 6 7 8 |
ropsten: { provider: () => new HDWalletProvider(mnemonic, `https://ropsten.infura.io/v3/${infuraKey}`), network_id: 3, // Ropsten's id gas: 5500000, // Ropsten has a lower block limit than mainnet confirmations: 2, // # of confs to wait between deployments. (default: 0) timeoutBlocks: 200, // # of blocks before a deployment times out (minimum/default: 50) skipDryRun: true // Skip dry run before migrations? (default: false for public nets ) }, |
infuraKey(ENDPOINT) の取得
アカウントを取得し、ログインしたらプロジェクトを作成します。
適当なプロジェクト名を付けます。
「VIEW PROJECT」をクリックします。
「PROJECT ID」が infuraKey となります。
コントラクトのコンパイルとマイグレーション
コンパイルする前に truffle-hdwallet-provider をインストールしておきます。
1 |
$ npm install truffle-hdwallet-provider |
インストールの際に下記のようなエラーになった場合は、Pythonのバージョンを2.x系に切り替えてみて下さい。3.x系だとうまくいかないようです。インストールした後に再度3.x系に戻しておくと良いでしょう。
1 2 3 4 5 6 7 8 9 10 11 |
〜省略 npm ERR! code ELIFECYCLE npm ERR! errno 1 npm ERR! sha3@1.2.3 install: `node-gyp rebuild` npm ERR! Exit status 1 npm ERR! npm ERR! Failed at the sha3@1.2.3 install script. npm ERR! This is probably not a problem with npm. There is likely additional logging output above. npm ERR! A complete log of this run can be found in: npm ERR! /Users/tadahiko/.npm/_logs/2019-08-10T01_36_21_466Z-debug.log |
コンパイルし、ROPSTEN Testnet にマイグレーション(デプロイ)します。
1 2 |
$ truffle compile $ truffle migrate --network ropsten |
成功すると下記のような表示になります。(2分程かかりました。)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
〜省略 2_deploy_contracts.js ===================== Deploying 'HelloWorld' ---------------------- > transaction hash: 0x38a84ba548d4ed2f80aad02ebdcae742ec4df5d852d0598192afe8cd779a976f > Blocks: 2 Seconds: 21 > contract address: 0x8b351c5ED9818441283AC49d4C683F4ab626f299 > block number: 6173345 > block timestamp: 1565571979 > account: 0x3Ffd57AEfd2E379f5D4758525dbEE2656Dd32Eb9 > balance: 4.00547727799979 > gas used: 301565 > gas price: 20 gwei > value sent: 0 ETH > total cost: 0.0060313 ETH Pausing for 2 confirmations... ------------------------------ > confirmation number: 1 (block: 6173345) > confirmation number: 2 (block: 6173346) > Saving migration to chain. > Saving artifacts ------------------------------------- > Total cost: 0.0060313 ETH Summary ======= > Total deployments: 2 > Final cost: 0.01125916 ETH |
10行目
contract address が作成したHelloWorldコントラクトのアドレスです。実際に下記リンクのEtherScanで確認することができます。
https://ropsten.etherscan.io/address/0x8b351c5ED9818441283AC49d4C683F4ab626f299
web3.jsでコントラクトにアクセスする
実際にROPSTEN TestnetにデプロイしたHelloWorldコントラクトにアクセスし「こんにちわ」を取得してみます。Node.jsのExpress を利用します。
関連ページ
適当なプロジェクトを作成し、初期化します。
1 2 3 |
$ mkdir hello-express $ cd hello-express/ $ npm init |
express と web3 をインストールします。
1 |
$ npm install --save express web3 |
package.json のdependencies項目は下記のように設定されました。
1 2 3 4 |
"dependencies": { "express": "^4.17.1", "web3": "^1.2.1" } |
index.js を作成し下記のように編集しました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
const express = require('express') const Web3 = require('web3') const app = express() //INFURA KEYS const infuraKey = "◯◯◯" //ABI情報 const HelloWorld = require('../build/contracts/HelloWorld.json') const abi = HelloWorld.abi //コントラクトのアドレス const contractAddress = "0x8b351c5ED9818441283AC49d4C683F4ab626f299" const provider = new Web3.providers.HttpProvider(`https://ropsten.infura.io/v3/${infuraKey}`) app.get('/', async (req, res) => { try { const web3 = new Web3(provider) const contract = new web3.eth.Contract(abi, contractAddress) const word = await contract.methods.getWord().call() res.send(word) } catch (err) { console.error(err) } }) app.listen(3000, () => { console.log('start') }) |
6行目
上述で説明した infuraKey を設定します。
20行目
コントラクトのインスタンスの生成には、ABI情報とコントラクトのアドレスが必要となります。
起動させて、下記リンクにアクセスするとブラウザ上に「こんにちわ」と表示されます。
デプロイしたコントラクトの changeWord関数の実行に関しては下記ページをご覧下さい。
ethereumjs-tx version 2 を利用する [Tx is not a constructor][invalid sender]