下載地址css
在谷歌應用商店
中搜索metamask
html
下載地址node
下載地址
安裝完成須要將node.exe所在路徑加入環境變量PATH中
而且須要保證在cmd中能夠使用node
和npm
命令,簡單測試:jquery
$ node -v $ npm -v
ganache
remix
切換運行環境。點擊remix
在線編輯器右側的run
->Environment
,選擇Injected Web3
metamask
鏈接ganache
。打開chrome瀏覽器中的metamask
插件,首先經過12個單詞短語恢復帳號。而後經過"Custom RPC", 輸入http://localhost:7545
,保存並將換網絡切換至http://localhost:7545
,鏈接成功後顯示主帳戶信息''$ mkdir demo $ cd demo $ npm init
後面所有enter
默認選擇(直接敲回車)就行了,效果以下:git
$ ls package.json $ cat package.json { "name": "demo", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", "license": "ISC" }
$ npm install ethereum/web3.js --save
安裝比較耗時, 須要耐心等待安裝完成
完成後效果:github
$ ls node_modules/ package.json package-lock.json $ ls node_modules/ bignumber.js/ crypto-js/ web3/ xmlhttprequest/ cookiejar/ utf8/ xhr2-cookies/ $ ls node_modules/web3/ bower.json example/ lib/ package.json styleguide.md circle.yml gulpfile.js* LICENSE.md package-init.js dist/ index.js package.js README.md # 發現配置已經發生了改變 $ cat package.json { "name": "demo", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", "license": "ISC", "dependencies": { "web3": "github:ethereum/web3.js" } }
在項目根目錄下建立index.html
和main.css
以下:web
$ ls demo index.html main.css node_modules/ package.json package-lock.json
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>DApp Demo</title> <link rel="stylesheet" type="text/css" href="main.css"> <script src="./node_modules/web3/dist/web3.min.js"></script> <script src="https://cdn.bootcss.com/jquery/1.12.4/jquery.js"></script> </head> <body> <div class="container"> <h1>Simple DApp Demo</h1> <h2 id="info"></h2> <label for="name" class="col-lg-2 control-label">Name</label> <input id="name" type="text"> <label for="age" class="col-lg-2 control-label">Age</label> <input id="age" type="text"> <button id="button">更新我的信息</button> </div> <script> window.addEventListener('load', function () { if (typeof web3 !== 'undefined') { web3 = new Web3(web3.currentProvider); } else { web3 = new Web3(new Web3.providers.HttpProvider("http://127.0.0.1:7545")); } //web3.eth.defaultAccount = web3.eth.accounts[0]; // replace with your abi code const abi = [ { "constant": false, "inputs": [ { "name": "_name", "type": "string" }, { "name": "_age", "type": "uint256" } ], "name": "setPersonalInfo", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [], "name": "getPersonalInfo", "outputs": [ { "name": "", "type": "string" }, { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" } ]; // replace with your contract address const address = "0x0d4aed2bf6178c870355ce1100a11e8fafdbd15d"; // create contract instance const PersonalInfo = web3.eth.contract(abi).at(address); console.log("PersonalInfoContract:", PersonalInfo); PersonalInfo.getPersonalInfo(function (error, result) { if (!error) { $("#info").html(result[0] + ' (' + result[1] + ' years old)'); console.log("get PersonalInfo success: ", result); } else { console.error("failed to get PersonalInfo :", error); } }); $("#button").click(function () { var name = $("#name").val(); var age = $("#age").val(); PersonalInfo.setPersonalInfo(name, age, function (error, result) { if (!error) { // update label $("#info").html(name + ' (' + age + ' years old)'); console.log("setPersonalInfo success: " + result); } else { consoe.log("fail to setPersonalInfo: " + error); } }); }); }); </script> </body> </html>
body { background-color:#F0F0F0; padding: 2em; font-family: 'Raleway','Source Sans Pro', 'Arial'; } .container { width: 50%; margin: 0 auto; } label { display:block; margin-bottom:10px; } input { padding:10px; width: 50%; margin-bottom: 1em; } button { margin: 2em 0; padding: 1em 4em; display:block; } #info { padding:1em; background-color:#fff; margin: 1em 0; }
使用solidity在線編輯器remix
solidity
代碼以下:chrome
pragma solidity ^0.4.16; contract PersonalInfo { string name; uint age; function setPersonalInfo(string _name, uint _age) public { name =_name; age = _age; } function getPersonalInfo() public view returns(string, uint){ return (name, age); } }
Due to browser security restrictions, we can't communicate with dapps running on file://. Please use a local server for development.npm
若是直接使用瀏覽器打開index.html會出現跨域訪問,以下圖:
json
The MetaMask Web3 object does not support synchronous methods like eth_sendTransaction without a callback parameter
官方解釋:
All Async - Think of MetaMask as a light client
The user does not have the full blockchain on their machine, so data lookups can be a little slow. For this reason, we are unable to support most synchronous methods. The exceptions to this are:
在合約實例調用對應函數的時候,加上回調函數。形如:
PersonalInfoContract.setPersonalInfo(name, age, function (error, result) { if (!error) { // update label $("#info").html(name + ' (' + age + ' years old)'); console.log("setPersonalInfo success: " + result); } else { consoe.log("fail to setPersonalInfo: " + error); } });
參考: