-
Notifications
You must be signed in to change notification settings - Fork 0
基本的なトークンの作り方
OpenZeppelin使うのが定番
- OpenZeppelinはバージョンの違いでかなりの変更が起きるケースがあるっぽいので--saveではなく-Eを利用するのがポイント
- -E (--save-exact)
- バージョンを確認するのも重要
npm install -g truffle
mkdir myproject && cd myproject
truffle init
npm init -y
npm install -E openzeppelin-solidity
touch contracts/ExampleToken.sol
touch migrations/2_deploy_contracts.js
ganache-cli
Version確認
truffle version
Truffle v4.1.12 (core: 4.1.12)
Solidity v0.4.24 (solc-js)
node version
v8.8.1
cat contracts/Migrations.sol
pragma solidity ^0.4.23;
"openzeppelin-solidity": "1.10.0"
StandardTokenを使うとよい、MintableTokenとかでもOK。
ExampleToken.sol
decimalsが18のトークンを100000作成
pragma solidity ^0.4.23;
import "openzeppelin-solidity/contracts/token/ERC20/StandardToken.sol";
contract ExampleToken is StandardToken {
string public name = "ExampleToken";
string public symbol = "EGT";
uint public decimals = 18;
uint public INITIAL_SUPPLY = 10000 * (10 ** decimals);
constructor() public {
totalSupply_ = INITIAL_SUPPLY;
balances[msg.sender] = INITIAL_SUPPLY;
}
}
Migrationファイル設定
2_deploy_contracts.js
var coin = artifacts.require("./ExampleCoin.sol");
module.exports = function(deployer) {
deployer.deploy(coin);
};
truffle.js設定
module.exports = {
networks: {
development: {
host: "localhost",
port: 8545,
network_id: "*" // Match any network id
}
}
};
コンパイルとマイグレーション
truffle compile
truffle migrate
ちなみにマイグレーションリセットはよく使う
truffle migrate --reset
Consoleからのdeployと各種基本処理
[~]$ truffle console
// デプロイ
ExampleToken.deployed().then(inst => { token = inst })
token.totalSupply()
BigNumber { s: 1, e: 22, c: [ 100000000 ] }
owner = web3.eth.accounts[0]
token.balanceOf(owner)
BigNumber { s: 1, e: 22, c: [ 100000000 ] }
receiver = web3.eth.accounts[1]
// トークンの送信
token.transfer(receiver, web3.toWei(1, "ether"))
token.balanceOf(owner)
BigNumber { s: 1, e: 21, c: [ 99990000 ] }
token.balanceOf(receiver)
BigNumber { s: 1, e: 18, c: [ 10000 ] }
token.balanceOf(owner).then(balance => ownerBalance = balance.toString(10))
'9999000000000000000000'
web3.fromWei(ownerBalance, "ether")
'9999'
MintableToken利用すると、オーナー変更したり新しくコイン作れたりして便利 クラウドセールとかをする時はオーナーを変更して実行する
ExampleTokenをStandardTokenからMintableTokenに変更
pragma solidity ^0.4.23;
import "openzeppelin-solidity/contracts/token/ERC20/MintableToken.sol";
contract ExampleToken is MintableToken {
string public name = "ExampleToken";
string public symbol = "EGT";
uint public decimals = 18;
uint public INITIAL_SUPPLY = 10000 * (10 ** decimals);
constructor() public {
totalSupply_ = INITIAL_SUPPLY;
balances[msg.sender] = INITIAL_SUPPLY;
}
}
コンパイルとマイグレーション
truffle compile
truffle migration --reset
コンソールからの各種処理
[~]$ truffle console
ExampleToken.deployed().then(inst => { token = inst })
owner = web3.eth.accounts[0]
token.balanceOf(owner)
BigNumber { s: 1, e: 22, c: [ 100000000 ] }
// コイン作成
token.mint(owner, 1 * 10 ** 18)
token.balanceOf(owner)
BigNumber { s: 1, e: 22, c: [ 100010000 ] }
// オーナー変更
newOwner = web3.eth.accounts[1]
token.transferOwnership(newOwner)
// オーナーでなくなったので、コインの作成ができなくなる
token.mint(owner, 1 * 10 ** 18)
Error: VM Exception while processing transaction: revert
BurnableToken利用すると、コインを減らすことができる burnはpublic関数なので、だれでも自分のコインを減らせることに注意
ExampleTokenにBurnableTokenを追加
pragma solidity ^0.4.23;
import "openzeppelin-solidity/contracts/token/ERC20/MintableToken.sol";
import "openzeppelin-solidity/contracts/token/ERC20/BurnableToken.sol";
contract ExampleToken is MintableToken, BurnableToken {
string public name = "ExampleToken";
string public symbol = "EGT";
uint public decimals = 18;
uint public INITIAL_SUPPLY = 10000 * (10 ** decimals);
constructor() public {
totalSupply_ = INITIAL_SUPPLY;
balances[msg.sender] = INITIAL_SUPPLY;
}
}
コンパイルとマイグレーション
truffle compile
truffle migration --reset
コンソールからの各種処理
[~]$ truffle console
ExampleToken.deployed().then(inst => { token = inst })
owner = web3.eth.accounts[0]
token.balanceOf(owner)
BigNumber { s: 1, e: 22, c: [ 100000000 ] }
// コインを減少させる
token.burn(1 * 10 ** 18)
token.balanceOf(owner)
BigNumber { s: 1, e: 21, c: [ 99990000 ] }
// コインの増加も可能
token.mint(owner, 1 * 10 ** 18)
token.balanceOf(owner)
BigNumber { s: 1, e: 22, c: [ 100000000 ] }
truffle init
truffle create contract ExampleCoin
truffle compile
truffle migrate
truffle migrate --reset
truffle console
truffle develop
truffle test
migrate --reset
ネットワークにデプロイするためにライブラリ追加
npm install --save-dev dotenv truffle-wallet-provider ethereumjs-wallet
- .envファイルをルートディレクトリに作成し、以下のようにWalletのプライベートキーを指定する
- mainnetを使わない場合は、ropstenのキー設定しておくとよい
- なんも設定してないとWallet作成エラーになる
.env
ROPSTEN_PRIVATE_KEY="key"
MAINNET_PRIVATE_KEY="key"
truffle.jsを編集して各種ネットワークの情報を設定する
truffle.js
const WalletProvider = require("truffle-wallet-provider");
const Wallet = require('ethereumjs-wallet');
require('dotenv').config();
var ropstenPrivateKey = new Buffer(process.env["ROPSTEN_PRIVATE_KEY"], "hex")
var mainnetPrivateKey = new Buffer(process.env["MAINNET_PRIVATE_KEY"], "hex")
var ropstenWallet = Wallet.fromPrivateKey(ropstenPrivateKey);
var ropstenProvider = new WalletProvider(ropstenWallet, "https://ropsten.infura.io/");
var mainnetWallet = Wallet.fromPrivateKey(mainnetPrivateKey);
var mainnetProvider = new WalletProvider(mainnetWallet, "https://mainnet.infura.io/");
module.exports = {
// See <http://truffleframework.com/docs/advanced/configuration>
// to customize your Truffle configuration!
networks: {
development: {
host: "127.0.0.1",
port: 9545,
network_id: "*"
},
ropsten: {
provider: ropstenProvider,
// You can get the current gasLimit by running
// truffle deploy --network ropsten
// truffle(rinkeby)> web3.eth.getBlock("pending", (error, result) =>
// console.log(result.gasLimit))
network_id: "3",
},
mainnet: {
provider: mainnetProvider,
network_id: "1",
}
}
};
デプロイにはイーサリアムが必要になるので、ある程度ウォレットにいれておく必要あり
- テスト環境(ropsten)のfaucet(ethereumもらえるところ)
- http://faucet.ropsten.be:3001/
- 1etheあればデプロイできる感じ
- 合計大体0.3ether程度必要?
デプロイには数十秒~数分程度時間がかかる
ropstenへのデプロイ
truffle deploy --network ropsten
リセットもできる
truffle deploy --network ropsten --reset
出力結果
Using network 'ropsten'.
Running migration: 1_initial_migration.js
Replacing Migrations...
... 0x8c9031e696ae2d2b19a1ce3f57c14c7226adec8ddcf77772a2615b7b8935acfe
Migrations: 0xbe1aece5bb028e55f6c96484892eface79a2852e
Saving successful migration to network...
... 0xea11b368c94006c69c06e6c60f2c96282d745a10f6d08c663957c7fecc9b0b27
Saving artifacts...
Running migration: 2_deploy_contracts.js
Replacing ExampleToken...
... 0x83de8926b343f55ea88c936df4d60f23408b0b2b98f15b65f020795df7798c0f
ExampleToken: 0xe6897689c73ea878beb5ff9f698ee4e493c13ba9
Saving successful migration to network...
... 0xe1387484779544dd630ad74525bca82ee4030883f73e013798c212c548a01e97
Saving artifacts...
mainnetへのデプロイ
truffle deploy --network mainnet
デプロイしたトークンはコンソールから制御することもできる
- mintやburnは結構時間がかかる
truffle console --network ropsten
truffle(ropsten)>
token.totalSupply()
BigNumber { s: 1, e: 22, c: [ 100000000 ] }
owner = "0x3dfCEDa23dB363e651e3c3845f4ec54cB5D904eA"
token.balanceOf(owner)
BigNumber { s: 1, e: 22, c: [ 100000000 ] }
token.mint(owner , 1 * 10 ** 18)
token.balanceOf(owner)
BigNumber { s: 1, e: 22, c: [ 100010000 ] }
token.burn(1 * 10 ** 18)
token.balanceOf(owner)
BigNumber { s: 1, e: 22, c: [ 100000000 ] }
- トランザクション(tx)はetherscanで確認できる
-
- etherscanでデプロイしたアドレスを検索し、きちんとデプロイできてるのか確認する
- https://ropsten.etherscan.io/token/deployed_token_address
-
アカウントの情報も確認できる
-
owner
-
token
- EtherScanで変更できる情報
- Code(Verify and Publish your Solidity Source Code )
- Link(Project Link)
Are you The Contract Creator? Verify And Publish*New your Contract Source Code Today!
- codeを公開する場合、以下の情報が必要になる
- Contract Name
- solc version
- Optimization
- Solidity Contract Code
- Constructor Arguments ABI-encoded
- https://ropsten.etherscan.io/verifyContract
solcのバージョンは、出力されたbuild/contracts/ExampleToken.jsonに記載されている
Contract Name
ExampleToken
solc version
0.4.24+commit.e67f0147.Emscripten.clang
Optimization
NO
FlattenされたSolidityのCodeを確認するために、truffle-flattenerをインストールする
npm install truffle-flattener -g
Flattenされたコードを出力してコピーする
/usr/local/bin/truffle-flattener ./contracts/ExampleToken.sol | pbcopy
Code
Constructor Arguments ABI-encoded
-
Constructorのパラメーターとのこと
-
https://ethereum.stackexchange.com/questions/41015/how-get-constructor-arguments-abi-encoded
-
https://blog.de-swaef.eu/verify-truffle-contracts-on-etherscan/
-
https://abi.hashex.org/ を使うのが良さそう?
- build/contracts/ExampleToken.jsonのabiのみとってきて利用
今回はコンストラクタにパラメーターがないのでこれは利用しないでよい
無事コード公開できた模様
参考リンク
- https://medium.com/coinmonks/how-to-verify-and-publish-on-etherscan-52cf25312945
- https://michalzalecki.com/how-to-verify-smart-contract-on-etherscan/
プロジェクト情報のリンクの付け方
- 残念ながらメインネット以外は使えないっぽい
- Contractの作成者かオーナーのウォレットで認証すればできるようになる感じ
-
https://blog.zeppelin.solutions/the-hitchhikers-guide-to-smart-contracts-in-ethereum-848f08001f05
-
- Crowdsaleまで説明してある
- console tipsも良い
-
https://truffleframework.com/tutorials/robust-smart-contracts-with-openzeppelin
-
- ネットワークへのデプロイ方法説明
-
truffle-flattener
- https://www.npmjs.com/package/truffle-flattener
- solコードのflattener