知乎專欄 | 多維度架構 | | | 微信號 netkiller-ebook | | | QQ群:128659835 請註明“讀者” |
truffle 自帶一個開發環境
neo@netkiller ~/ethereum/truffle-project % 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 Private Keys: (0) c87509a1c067bbde78beb793e6fa76530b6382a4c0241e5e4a9ec0a0f44dc0d3 (1) ae6ae8e5ccbfb04590405997ee2d52d2b330726137b875053c36d94e974d162f (2) 0dbbe8e4ae425a6d2687f1a7e3ba17bc98c673636790f1b8ad91193c05875ef1 (3) c88b703fb08cbea894b6aeff5a544fb92e78a18e19814cd85da83b71f772aa6c (4) 388c684f0ba1ef5017716adb5d21a053ea8e90277d0868337519f97bede61418 (5) 659cbb0e2411a44db63778987b1e22153c086a95eb6b18bdf89de078917abc63 (6) 82d052c865f5763aad42add438569276c00d3d88a2d062d36b2bae914d58b8c8 (7) aa3680d5d48a8283413f7a108367c7299ca73f553735860a87b08f39395618b7 (8) 0f62d96d6675f32685bbdb8ac13cda7c23436f63efbb9d07700d8669ff12b7c4 (9) 8d5366123cb560bb606379f90a0bfd4769eecc0557f1b362dcae9012b548b1e5 Mnemonic: candy maple cake sugar pudding cream honey rich smooth crumble sweet treat truffle(develop)>
truffle develop 的作用於 testrpc 類似。
neo@netkiller ~/ethereum/truffle-project % testrpc EthereumJS TestRPC v6.0.3 (ganache-core: 2.0.2) Available Accounts ================== (0) 0xb5fd43ee8fa5ce1db9a30a25ba385ee3bfc72966 (1) 0xf5a732345734e1f0f49cbadb145a20d1e1a44b95 (2) 0x834fcd8c55fdf21fd14c82e9a1ef5d3636a2fed6 (3) 0x5aa4d047d85727309d3ca653c83c3bb0ecd18903 (4) 0xb4db2dede86f4539e56ac4438f6e36f09c307e46 (5) 0x8da382b1a10ab2f1dc149e19fda228a07c78935c (6) 0xb290297e89b52713548ff93e5fc23bc3c4183dde (7) 0x546183289bd4d9d33a3aee0ee663c0729926e583 (8) 0xca58321e442533b7f827e6e8976e1905acd15214 (9) 0xe2c0b336bbb03564204e15a2cb7744564a53efcc Private Keys ================== (0) ff32f7a06e2fb26b51a745c1e428c60df92c0f9bb3301b19a5b7e0cdfaae521a (1) cdbfe40321b6ade8a246748df1c48a738b8a531aee4d1f60a45bfd7f941e0064 (2) 7092117c2d7832980945e18645a60a1ed0e59261d040749f8b5202c2fc653d74 (3) f329657c9ad808e9f794a7462a1a9c276266343d5ced263ab618b6a19d6857c1 (4) 1221766592618add3a57ab109f00efcc70867dd8a9b10a0f7ea75c2b619edfc3 (5) c27005d6c3581193124c84766cc0b1cc318cb201b7d00b1035f4a4c7767ba790 (6) 6b7f43dca1dcc00203b751191096bb0602e17a9a94dcee8b846329efa703cea9 (7) 41be5971d71935bc88c3cf8aefd78ed3188c8721b7134cda3b25d353faf05d4f (8) bd4c9d512a4f2da2cdcd9e4f89c049e3e7ac81bf57a05369997c2f13e793bebb (9) 04196d803f743cc1fd021e7d02d5a552f14ab9826ccd4d4b265ff96c45169d2c HD Wallet ================== Mnemonic: confirm shift cable melody caught swing erode language spend victory conduct van Base HD Path: m/44'/60'/0'/0/{account_index} Listening on localhost:8545
cd ~/ethereum mkdir truffle-project cd truffle-project truffle init
操作演示
neo@netkiller ~/ethereum/truffle-project % truffle init Downloading... Unpacking... Setting up... Unbox successful. Sweet! Commands: Compile: truffle compile Migrate: truffle migrate Test contracts: truffle test neo@netkiller ~/ethereum/truffle-project % tree . |-- contracts | `-- Migrations.sol |-- migrations | `-- 1_initial_migration.js |-- test |-- truffle-config.js `-- truffle.js 3 directories, 4 files
目錄結構簡單說明如下:
contract/ - Truffle預設的合約檔案存放地址。
migrations/ - 存放發佈腳本檔案
test/ - 用來測試應用和合約的測試檔案
truffle.js - Truffle的配置檔案
app/ - 需要用戶創建,應用檔案運行的預設目錄。
pragma solidity ^0.4.18; contract Netkiller { string name; int num; function Netkiller() public{ name = "default"; num = 1; } function setName(string _name) public{ name = _name; } function getName() public view returns(string){ return name; } function setNum(int n) public{ num = n; } function addNum(int m) public view returns(int res){ res = m + num; } }
neo@netkiller ~/ethereum/truffle-project % vim migrations/2_initial_migration.js var Netkiller = artifacts.require("./Netkiller.sol"); module.exports = function(deployer) { deployer.deploy(Netkiller); };
打開檔案 truffle.js
module.exports = { // See <http://truffleframework.com/docs/advanced/configuration> // to customize your Truffle configuration! };
修改為
module.exports = { // See <http://truffleframework.com/docs/advanced/configuration> // to customize your Truffle configuration! networks: { development: { host: "localhost", port: 9545, network_id: "*" // Match any network id } } };
neo@netkiller ~/ethereum/truffle-project % truffle compile Compiling ./contracts/Migrations.sol... Compiling ./contracts/Netkiller.sol... Writing artifacts to ./build/contracts
truffle預設只會編譯最後一次修改過的合約檔案, 這是為了減少比重複編譯。"--all"選項,可以強制編譯所有檔案。
編譯結果
neo@netkiller ~/ethereum/truffle-project % find build build build/contracts build/contracts/Migrations.json build/contracts/Netkiller.json
Mac 環境
neo@MacBook-Pro ~/ethereum/truffle % node --version v9.5.0 neo@MacBook-Pro ~/ethereum/truffle % npm version { npm: '5.6.0', ares: '1.13.0', cldr: '32.0.1', http_parser: '2.7.0', icu: '60.2', modules: '59', napi: '2', nghttp2: '1.29.0', node: '9.5.0', openssl: '1.0.2n', tz: '2017c', unicode: '10.0', uv: '1.19.1', v8: '6.2.414.46-node.18', zlib: '1.2.11' } neo@MacBook-Pro ~/ethereum/truffle % truffle version Truffle v4.0.6 (core: 4.0.6) Solidity v0.4.19 (solc-js)
創建項目並初始化
mkdir -p ~/ethereum/truffle cd ethereum/truffle truffle init
truffle 自帶一個開發環境
neo@netkiller ~/ethereum/truffle-project % 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 Private Keys: (0) c87509a1c067bbde78beb793e6fa76530b6382a4c0241e5e4a9ec0a0f44dc0d3 (1) ae6ae8e5ccbfb04590405997ee2d52d2b330726137b875053c36d94e974d162f (2) 0dbbe8e4ae425a6d2687f1a7e3ba17bc98c673636790f1b8ad91193c05875ef1 (3) c88b703fb08cbea894b6aeff5a544fb92e78a18e19814cd85da83b71f772aa6c (4) 388c684f0ba1ef5017716adb5d21a053ea8e90277d0868337519f97bede61418 (5) 659cbb0e2411a44db63778987b1e22153c086a95eb6b18bdf89de078917abc63 (6) 82d052c865f5763aad42add438569276c00d3d88a2d062d36b2bae914d58b8c8 (7) aa3680d5d48a8283413f7a108367c7299ca73f553735860a87b08f39395618b7 (8) 0f62d96d6675f32685bbdb8ac13cda7c23436f63efbb9d07700d8669ff12b7c4 (9) 8d5366123cb560bb606379f90a0bfd4769eecc0557f1b362dcae9012b548b1e5 Mnemonic: candy maple cake sugar pudding cream honey rich smooth crumble sweet treat truffle(develop)>
創建合約檔案 contracts/Greeter.sol
pragma solidity ^0.4.20; contract Greeter { address creator; string greeting; function Greeter() public { creator = msg.sender; greeting = "default"; } function greet() constant public returns (string) { return greeting; } function setGreeting(string _newgreeting) public { greeting = _newgreeting; } function kill() public { if (msg.sender == creator) selfdestruct(creator); } }
創建部署檔案 migrations/2_initial_migration.js
var Greeter = artifacts.require("./Greeter.sol"); module.exports = function(deployer) { deployer.deploy(Greeter); };
打開檔案 truffle.js
module.exports = { // See <http://truffleframework.com/docs/advanced/configuration> // to customize your Truffle configuration! };
修改為
module.exports = { // See <http://truffleframework.com/docs/advanced/configuration> // to customize your Truffle configuration! networks: { development: { host: "localhost", port: 9545, network_id: "*" // Match any network id } } };
編譯並部署合約
neo@MacBook-Pro ~/ethereum/truffle % truffle compile Compiling ./contracts/Greeter.sol... Writing artifacts to ./build/contracts neo@MacBook-Pro ~/ethereum/truffle % truffle migrate --reset Using network 'development'. Running migration: 1_initial_migration.js Replacing Migrations... ... 0xddeac9a1c57772df50064f11227fcb5515e54a3e88e15843f5c0bc1b55a0dad7 Migrations: 0x2c2b9c9a4a25e24b174f26114e8926a9f2128fe4 Saving successful migration to network... ... 0x9b51540f5a7d75a8fc920e3e5e4ec66792ba31fd006bd176901f0e6347af2dba Saving artifacts... Running migration: 2_initial_migration.js Deploying Greeter... ... 0x312ead931bbe4b288315317bdf6735ba4fe4f30c20382f085ca27be345819983 Greeter: 0xfb88de099e13c3ed21f80a7a1e49f8caecf10df6 Saving successful migration to network... ... 0x69eaa7ed49cc72426706d54c4f52ba70b742ed6910f1223eb0df5f250b4b8ec3 Saving artifacts...
測試腳本
Greeter.deployed().then(instance => console.log(instance.address)) var contract; Greeter.deployed().then(function(instance){contract= instance;}); contract.greet(); contract.setGreeting("http://www.netkiller.cn") contract.greet();
進入控制台,交互執行上面程序
neo@MacBook-Pro ~/ethereum/truffle % truffle console truffle(development)> truffle(development)> Greeter.deployed().then(instance => console.log(instance.address)) 0x82d50ad3c1091866e258fd0f1a7cc9674609d254 undefined truffle(development)> var contract; undefined truffle(development)> Greeter.deployed().then(function(instance){contract= instance;}); undefined truffle(development)> contract.greet(); 'default' truffle(development)> contract.setGreeting("http://www.netkiller.cn") { tx: '0xa5cbfba78c84415517740a482c2bf2208da0c6b0ecabcd5c22db2c85749041c8', receipt: { transactionHash: '0xa5cbfba78c84415517740a482c2bf2208da0c6b0ecabcd5c22db2c85749041c8', transactionIndex: 0, blockHash: '0x557758e0d9b1ef81f41728cb92f43041d009751d5ce5e2e4424f7fb90f52041a', blockNumber: 16, gasUsed: 34206, cumulativeGasUsed: 34206, contractAddress: null, logs: [], status: 1 }, logs: [] } truffle(development)> contract.greet(); 'http://www.netkiller.cn'
[ethereum@netkiller truffle]$ cat contracts/TokenERC20.sol pragma solidity ^0.4.20; contract TokenERC20 { address public owner; // Public variables of the token string public name; string public symbol; uint8 public decimals = 2; // 18 decimals is the strongly suggested default, avoid changing it uint256 public totalSupply; // This creates an array with all balances mapping (address => uint256) public balanceOf; mapping (address => mapping (address => uint256)) public allowance; // This generates a public event on the blockchain that will notify clients event Transfer(address indexed from, address indexed to, uint256 value); // This notifies clients about the amount burnt event Burn(address indexed from, uint256 value); mapping (address => bool) public frozenAccount; event FrozenFunds(address target, bool frozen); /** * Constrctor function * * Initializes contract with initial supply tokens to the creator of the contract */ function TokenERC20( uint256 initialSupply, string tokenName, string tokenSymbol ) public { owner = msg.sender; totalSupply = initialSupply * 10 ** uint256(decimals); // Update total supply with the decimal amount balanceOf[msg.sender] = totalSupply; // Give the creator all initial tokens name = tokenName; // Set the name for display purposes symbol = tokenSymbol; // Set the symbol for display purposes } modifier onlyOwner { require(msg.sender == owner); _; } /** * Internal transfer, only can be called by this contract */ function _transfer(address _from, address _to, uint _value) internal { // Prevent transfer to 0x0 address. Use burn() instead require(_to != 0x0); // Check if the sender has enough require(balanceOf[_from] >= _value); // Check for overflows require(balanceOf[_to] + _value > balanceOf[_to]); // Save this for an assertion in the future uint previousBalances = balanceOf[_from] + balanceOf[_to]; // Subtract from the sender balanceOf[_from] -= _value; // Add the same to the recipient balanceOf[_to] += _value; // Asserts are used to use static analysis to find bugs in your code. They should never fail assert(balanceOf[_from] + balanceOf[_to] == previousBalances); } function transfer(address _to, uint256 _value) public { require(!frozenAccount[msg.sender]); _transfer(msg.sender, _to, _value); } function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) { require(!frozenAccount[msg.sender]); require(_value <= allowance[_from][msg.sender]); // Check allowance allowance[_from][msg.sender] -= _value; _transfer(_from, _to, _value); return true; } function approve(address _spender, uint256 _value) public returns (bool success) { allowance[msg.sender][_spender] = _value; return true; } function approveAndCall(address _spender, uint256 _value) public returns (bool success) { if (approve(_spender, _value)) { return true; } } function burn(uint256 _value) onlyOwner public returns (bool success) { require(balanceOf[msg.sender] >= _value); // Check if the sender has enough balanceOf[msg.sender] -= _value; // Subtract from the sender totalSupply -= _value; // Updates totalSupply return true; } function burnFrom(address _from, uint256 _value) onlyOwner public returns (bool success) { require(balanceOf[_from] >= _value); // Check if the targeted balance is enough require(_value <= allowance[_from][msg.sender]); // Check allowance balanceOf[_from] -= _value; // Subtract from the targeted balance allowance[_from][msg.sender] -= _value; // Subtract from the sender's allowance totalSupply -= _value; // Update totalSupply return true; } function transfer(address _to, uint256 _value, bytes _data) public returns (bool) { require(_to != address(this)); transfer(_to, _value); require(_to.call(_data)); return true; } function transferFrom(address _from, address _to, uint256 _value, bytes _data) public returns (bool) { require(_to != address(this)); transferFrom(_from, _to, _value); require(_to.call(_data)); return true; } function approve(address _spender, uint256 _value, bytes _data) public returns (bool) { require(_spender != address(this)); approve(_spender, _value); require(_spender.call(_data)); return true; } function transferOwnership(address _owner) onlyOwner public { owner = _owner; } function mintToken(address target, uint256 mintedAmount) public onlyOwner { balanceOf[target] += mintedAmount; totalSupply += mintedAmount; } function freezeAccount(address target, bool freeze) public onlyOwner { frozenAccount[target] = freeze; } }
[ethereum@netkiller truffle]$ cat migrations/2_initial_token.js var TokenERC20 = artifacts.require("./TokenERC20.sol"); module.exports = function(deployer) { deployer.deploy(TokenERC20,1200000000,"Netkiller Coin","NKC"); };
[ethereum@netkiller truffle]$ truffle compile Compiling ./contracts/Migrations.sol... Compiling ./contracts/TokenERC20.sol... Writing artifacts to ./build/contracts [ethereum@netkiller truffle]$ truffle migrate Using network 'development'. Running migration: 1_initial_migration.js Deploying Migrations... ... 0x80746c040d6c6ed8178f90d74356a994fea81516bdd6579d003c433d7a0a0116 Migrations: 0x8cdaf0cd259887258bc13a92c0a6da92698644c0 Saving successful migration to network... ... 0xd7bc86d31bee32fa3988f1c1eabce403a1b5d570340a3a9cdba53a472ee8c956 Saving artifacts... Running migration: 2_initial_token.js Deploying TokenERC20... ... 0xb375b52fe6df9f298828672f3ba3560d7a6f6806ce344e964439d0febc13cb97 TokenERC20: 0x345ca3e014aaf5dca488057592ee47305d9b3e10 Saving successful migration to network... ... 0xf36163615f41ef7ed8f4a8f192149a0bf633fe1a2398ce001bf44c43dc7bdda0 Saving artifacts...
[ethereum@netkiller truffle]$ truffle console truffle(development)> var contract; undefined truffle(development)> TokenERC20.deployed().then(function(instance){contract=instance;}); undefined truffle(development)> contract.symbol.call().then(console.log); NKC truffle(development)> contract.name.call().then(console.log); Netkiller Coin
解鎖賬號,查看 gas limit 價格
[ethereum@netkiller ~]$ geth attach Welcome to the Geth JavaScript console! instance: Geth/v1.8.7-stable/linux-amd64/go1.10.2 coinbase: 0x8232ef29d29f46d3621350ab7097604247ed4830 at block: 2863 (Fri, 11 May 2018 17:16:01 CST) datadir: /home/ethereum/.ethereum modules: admin:1.0 debug:1.0 eth:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0 > personal.unlockAccount(eth.accounts[0],"12345678",50000) true > web3.eth.getBlock("pending").gasLimit 4712388 > exit
配置 truffle.js
[ethereum@netkiller truffle]$ cat truffle.js module.exports = { // See <http://truffleframework.com/docs/advanced/configuration> // to customize your Truffle configuration! networks: { development: { host: "localhost", port: 8545, gas: 4712388, network_id: "*" // Match any network id } } };
[ethereum@netkiller truffle]$ truffle compile (node:23256) ExperimentalWarning: The fs.promises API is experimental Compiling ./contracts/NetkillerAdvancedToken.sol... Writing artifacts to ./build/contracts
[ethereum@netkiller truffle]$ truffle migrate (node:23456) ExperimentalWarning: The fs.promises API is experimental Using network 'development'. Running migration: 1_initial_migration.js Deploying Migrations... ... 0xa5937808d9d42dba231738d79d5989e160a2bbc02aa7e8938d0ee71a11eab9a7 Migrations: 0x0f6d790c0ce6453161ead810246602c601f836e7 Saving successful migration to network... ... 0xabd2d76488caa48eac5b9ad5d662b34a8b41acacb5657ff4f78c5c4530913d2b Saving artifacts... Running migration: 2_initial_token.js Deploying NetkillerAdvancedToken... ... 0x190239e85c54aa407ba8dd98357ebabbe2dcab65811f3c4aab7486af27436a09 NetkillerAdvancedToken: 0xb45bd60c48ea18991a5f25a644682d8cf7572ccf Saving successful migration to network... ... 0x97b9fffef368b2411341d9fed31bd771d0beebe02bde8c19c61a9e0dde0cc773 Saving artifacts...
var contract; NetkillerAdvancedTokenAirDrop.deployed().then(function(instance){contract=instance;}); contract.symbol.call().then(console.log); contract.name.call().then(console.log); contract.totalSupply.call().then(console.log); contract.balanceOf.call(web3.eth.accounts[0]).then(console.log);
contract.transfer(web3.eth.accounts[1],100).then(function(){contract.balanceOf.call(web3.eth.accounts[1]).then(console.log);});
contract.transferFrom(web3.eth.accounts[0],web3.eth.accounts[1],100).then(function(){contract.balanceOf.call(web3.eth.accounts[1]).then(console.log);});
contract.setLock(true); contract.transfer(web3.eth.accounts[2],100).then(function(){contract.balanceOf.call(web3.eth.accounts[2]).then(console.log);});
演示
truffle(development)> contract.setLock(true); { tx: '0x6a603ca9456b574224aa97b8bf1d66280fc8509c94253c0037bc5bb71135a667', receipt: { transactionHash: '0x6a603ca9456b574224aa97b8bf1d66280fc8509c94253c0037bc5bb71135a667', transactionIndex: 0, blockHash: '0x4e0893b5ff6b1d85182dca0ceb3c0c2cb750183ff856b7ad2e323ad2a3b55fdc', blockNumber: 13, gasUsed: 42424, cumulativeGasUsed: 42424, contractAddress: null, logs: [], status: 1 }, logs: [] } truffle(development)> contract.transfer(web3.eth.accounts[2],100).then(function(){contract.balanceOf.call(web3.eth.accounts[2]).then(console.log);}); Error: VM Exception while processing transaction: revert at XMLHttpRequest._onHttpResponseEnd (/usr/local/lib/node_modules/truffle/build/webpack:/~/xhr2/lib/xhr2.js:509:1) at XMLHttpRequest._setReadyState (/usr/local/lib/node_modules/truffle/build/webpack:/~/xhr2/lib/xhr2.js:354:1) at XMLHttpRequestEventTarget.dispatchEvent (/usr/local/lib/node_modules/truffle/build/webpack:/~/xhr2/lib/xhr2.js:64:1) at XMLHttpRequest.request.onreadystatechange (/usr/local/lib/node_modules/truffle/build/webpack:/~/web3/lib/web3/httpprovider.js:128:1) at /usr/local/lib/node_modules/truffle/build/webpack:/~/truffle-provider/wrapper.js:134:1 at /usr/local/lib/node_modules/truffle/build/webpack:/~/web3/lib/web3/requestmanager.js:86:1 at Object.InvalidResponse (/usr/local/lib/node_modules/truffle/build/webpack:/~/web3/lib/web3/errors.js:38:1)
解鎖後再測試
contract.setLock(false); contract.transfer(web3.eth.accounts[2],100).then(function(){contract.balanceOf.call(web3.eth.accounts[2]).then(console.log);});
truffle(development)> contract.setLock(false); { tx: '0x3d4b8d49626c1171ab7160274a9f573bb06999fa7bc33240704199c7905f62fd', receipt: { transactionHash: '0x3d4b8d49626c1171ab7160274a9f573bb06999fa7bc33240704199c7905f62fd', transactionIndex: 0, blockHash: '0x0c78b27d817449b6a3727a13041f1880cbf5466a8b81719f2541c08d59ca5fb3', blockNumber: 15, gasUsed: 13680, cumulativeGasUsed: 13680, contractAddress: null, logs: [], status: 1 }, logs: [] } truffle(development)> contract.transfer(web3.eth.accounts[2],100).then(function(){contract.balanceOf.call(web3.eth.accounts[2]).then(console.log);}); undefined truffle(development)> BigNumber { s: 1, e: 2, c: [ 100 ] }
[ethereum@netkiller ~]$ geth account new INFO [05-11|17:25:49] Maximum peer count ETH=25 LES=0 total=25 Your new account is locked with a password. Please give a password. Do not forget this password. Passphrase: Repeat passphrase: Address: {3c1ba8b80b9a8697f2e34194c2a73a93105be23d}
contract.mintAirdropToken(1000000); contract.totalAirdropSupply.call().then(console.log); contract.totalSupply.call().then(console.log); contract.setAirdrop(10); contract.setAirdropLock(true); contract.balanceOf.call(web3.eth.accounts[3]).then(console.log); contract.currentTotalAirdrop.call().then(console.log);
操作演示
[ethereum@netkiller ~]$ truffle console truffle(development)> var contract; NetkillerAdvancedTokenAirDrop.deployed().then(function(instance){contract=instance;});undefined truffle(development)> NetkillerAdvancedTokenAirDrop.deployed().then(function(instance){contract=instance;}); undefined truffle(development)> contract.mintAirdropToken(1000000); { tx: '0xab251fafc30724273259442fc02bfa429235ff14535f4fb25e29bed7de09ea11', receipt: { transactionHash: '0xab251fafc30724273259442fc02bfa429235ff14535f4fb25e29bed7de09ea11', transactionIndex: 0, blockHash: '0x5498eb579a08e8da1ca2d5ad3d6dd5b0a5c21cc9a630809783d09b65e26929b9', blockNumber: 28, gasUsed: 47701, cumulativeGasUsed: 47701, contractAddress: null, logs: [], status: 1 }, logs: [] } truffle(development)> contract.setAirdrop(10); { tx: '0xd8a3a16328373858e3cc30c7947b3c3c00db447bb3306f2cf2af58fd0215aef8', receipt: { transactionHash: '0xd8a3a16328373858e3cc30c7947b3c3c00db447bb3306f2cf2af58fd0215aef8', transactionIndex: 0, blockHash: '0x5be96cfd95031a132fc643b06d01dba0b14f736fa9fa3f16dd5bbd9c7f030700', blockNumber: 29, gasUsed: 42209, cumulativeGasUsed: 42209, contractAddress: null, logs: [], status: 1 }, logs: [] } truffle(development)> contract.setAirdropLock(true); { tx: '0x7b8b5747a64111a500cce22371d78b2c3c4ce0b5a2b585b26c0278876044e231', receipt: { transactionHash: '0x7b8b5747a64111a500cce22371d78b2c3c4ce0b5a2b585b26c0278876044e231', transactionIndex: 0, blockHash: '0xd6960add791b36afac1126a00af16f2833043dcb3416d68bb4056db64313dc93', blockNumber: 30, gasUsed: 42408, cumulativeGasUsed: 42408, contractAddress: null, logs: [], status: 1 }, logs: [] } truffle(development)> contract.balanceOf.call(web3.eth.accounts[5]).then(console.log); BigNumber { s: 1, e: 1, c: [ 10 ] } undefined