一 MetaMask
1 安裝MetaMask
通過(guò)Chrome瀏覽器安裝MetaMask插件,插件地址https://www.metamask.io/,選擇'GET CHROME EXTENSION'如下圖紅框。

注:如果安裝失敗,退出登錄再安裝,這是我遇到的一種情況。如果仍然失敗請(qǐng)留言。
2 生成MetaMask賬號(hào)
MetaMask插件安裝成功后,會(huì)出現(xiàn)一只狐貍?頭像,如下圖

點(diǎn)擊插件,設(shè)置密碼,創(chuàng)建賬號(hào)(也可以導(dǎo)入已有賬號(hào))如果是創(chuàng)建賬號(hào)記得保存好助記詞,這些操作不一一說(shuō)明了,有問(wèn)題請(qǐng)留言。
這里主要說(shuō)下幾個(gè)網(wǎng)絡(luò),一個(gè)是主網(wǎng),另外還有三個(gè)測(cè)試網(wǎng)絡(luò),我是在Rinkeby Test Network下完成的,各位也可以試試另外兩個(gè)測(cè)試網(wǎng)絡(luò),當(dāng)然用主網(wǎng)做開發(fā)是不可能的-窮。
下面講下如何申請(qǐng)Rinkeby Test Network的測(cè)試代幣。
打開rinkeby網(wǎng)站·地址:https://www.rinkeby.io/#faucet

我是通過(guò)google++的方式,需要FQ,這個(gè)大家自己豐衣足食,別干蠢事就行。

復(fù)制剛剛分享的信息地址,到rinkeby網(wǎng)站輸入地址申請(qǐng)測(cè)試幣。

到這時(shí)MetaMask錢包已準(zhǔn)備完成。
二 智能合約
1 編寫并發(fā)布智能合約
為做測(cè)試寫一個(gè)簡(jiǎn)單的智能合約,復(fù)雜的也憋不出來(lái)。
智能合約編輯器:http://remix.ethereum.org/#optimize=true&version=soljson-v0.4.24+commit.e67f0147.js

點(diǎn)擊Deploy,彈出MetaMask對(duì)話框,支付gas確認(rèn)發(fā)布

2 驗(yàn)證智能合約
合約發(fā)布成功后,會(huì)顯示發(fā)布合約的交易查詢地址。

點(diǎn)擊發(fā)布合約交易查詢地址,顯示如下

點(diǎn)擊合約地址,查詢合約詳細(xì)信息

驗(yàn)證合約

輸入以上5個(gè)地方的信息,點(diǎn)擊驗(yàn)證

驗(yàn)證成功后,保存合約地址和ABI信息,后續(xù)要用到。
3 合約內(nèi)容說(shuō)明
合約代碼(這只是一個(gè)測(cè)試合約,Solidity還不是很熟悉,如果合約有什么語(yǔ)法錯(cuò)誤,歡迎指教)
pragma solidity ^0.4.24;
contract GameContract {
? address fromAddress;
? uint256 value;
? uint256 code;
? uint256 team;
? function buyKey(uint256 _code, uint256 _team)
? ? public
? ? payable
? {
? ? ? fromAddress = msg.sender;
? ? ? value = msg.value;
? ? ? code = _code;
? ? ? team = _team;
? }
? function getInfo()
? ? public
? ? constant
? ? returns (address, uint256, uint256, uint256)
? {
? ? ? return (fromAddress, value, code, team);
? }?
? ?function withdraw()
? ? ? ? public
? ? {
? ? ? ? address send_to_address = 0xfdd7a3f5375C6Fcc7852C0372bCE202b3080F451;
? ? ? ? uint256 _eth = 333000000000000000;
? ? ? ? send_to_address.transfer(_eth);
? ? }
}
buyKey方法是向合約地址轉(zhuǎn)入eth,該方法有payable屬性,說(shuō)明可以轉(zhuǎn)入eth。在方法中通過(guò)msg.sender和msg.value,可以獲取eth的轉(zhuǎn)出地址(from_address)和數(shù)量(單位是wei),eth的轉(zhuǎn)入地址(to_address)就是合約地址。其它兩個(gè)參數(shù)是合約邏輯需要的數(shù)據(jù),可以有多個(gè)也可以沒有。(from_address=msg.sender;to_address=contract_address;value=msg.value)
getInfo方法是獲取buyKey方法轉(zhuǎn)入的信息。
withdraw方法是從合約地址中轉(zhuǎn)出eth,轉(zhuǎn)出地址(from_address)是合約地址,轉(zhuǎn)入地址(to_address)是send_to_address,數(shù)量是_eth(單位是wei)。
合約代碼說(shuō)明就這樣,不了解的一起學(xué)習(xí)。
三 通過(guò)WEB3調(diào)用智能合約
先貼代碼
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
MetaMask Test
Set Info!Get Info!Send Out!
? ? window.addEventListener('load', function() {
? ? if (typeof web3 !== 'undefined') {
? ? ? ? initContract(web3);
? ? ? ? initAccount(web3);
? ? }
});
var address = '';
// 初始化MetaMask當(dāng)前賬戶
function initAccount(web3) {
? ? // 獲取metamask當(dāng)前登錄的account
? ? web3.eth.getAccounts(function(err, accounts) {
? ? console.log(accounts);
? ? if (accounts!=null && accounts.length>0)
? ? address = accounts[0].toString();
? ? });
}
// 初始化合約對(duì)象
function initContract(web3) {
var abi = [{"constant":false,"inputs":[],"name":"withdraw","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getInfo","outputs":[{"name":"","type":"address"},{"name":"","type":"uint256"},{"name":"","type":"uint256"},{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_code","type":"uint256"},{"name":"_team","type":"uint256"}],"name":"buyKey","outputs":[],"payable":true,"stateMutability":"payable","type":"function"}];
var contract_address = '0xe5fe93d857900a84cb6be5429a06f825ca6d28fb'
? ? var eth = new Eth(web3.currentProvider)
? ? var contract = eth.contract(abi).at(contract_address);
? ? listenForClicks(contract, web3)
}
// 添加按鈕click事件
function listenForClicks (contract, web3) {
? ? var button = document.querySelector('button.setInfo');
? ? var button1 = document.querySelector('button.getInfo');
? ? var button2 = document.querySelector('button.sendOut');
? ? // 調(diào)用buyKey方法(eth轉(zhuǎn)入)
? ? button.addEventListener('click', function() {
var etherValue = web3.toWei(0.2, 'ether');
? ? ? ? contract.buyKey('1', '1', {from: address, value: etherValue}, function(error, result) {
? ? ? ? ? ? console.log('Send In')
if (!error)
? ? ? ? ? ? console.log(JSON.stringify(result));
? ? ? ? else
? ? ? ? ? ? console.error(error);
? ? ? ? });
? ? });
// 調(diào)用getInfo方法
? ? button1.addEventListener('click', function() {
? ? ? ? contract.getInfo(function(error, result) {
? ? ? ? ? ? console.log('Get Info')
if (!error) {
? ? ? ? ? ? console.log('fromAddress:' + result[0] + ', value:' + result[1]);
? ? ? ? ? ? console.log('code:' + result[2] + ', team:' + result[3]);
} else
? ? ? ? ? ? console.error(error);
? ? ? ? });
? ? });
// 調(diào)用withdraw方法(eth轉(zhuǎn)出)
? ? button2.addEventListener('click', function() {
? ? ? ? contract.withdraw({from: address}, function(error, result) {
? ? ? ? ? ? console.log('Send Out')
if (!error)
? ? ? ? ? ? console.log(JSON.stringify(result));
? ? ? ? else
? ? ? ? ? ? console.error(error);
? ? ? ? });
? ? });
}
是tomcat跑的jsp頁(yè)面,大家也可以用其它服務(wù)器
主要講下智能合約eth的轉(zhuǎn)入和轉(zhuǎn)出兩塊的代碼。
1 智能合約eth轉(zhuǎn)入方法的調(diào)用

智能合約中的buyKey只有兩個(gè)參數(shù),前面兩個(gè)參數(shù)就對(duì)應(yīng)了智能合約中的兩個(gè)參數(shù),紅框中的參數(shù)是eth轉(zhuǎn)出地址(from_account)和eht數(shù)量,單位是wei。


2?智能合約eth轉(zhuǎn)出方法的調(diào)用
如果實(shí)現(xiàn)了上一步,那就先祝賀你,現(xiàn)在我們?cè)倏纯粗悄芎霞seth的轉(zhuǎn)出,上一步成功后看到合約的eth數(shù)量是0.2個(gè),而轉(zhuǎn)出方法中我們寫的數(shù)量是0.333個(gè),所以還需要向合約轉(zhuǎn)入eth,再調(diào)用一次buyKey方法

調(diào)用合約eth轉(zhuǎn)出方法

這個(gè)地方也有{from: address}參數(shù),但是這個(gè)不是eth轉(zhuǎn)出地址。因?yàn)檫@個(gè)方法內(nèi)部有eth的交易,所以需要支付gas,這個(gè)參數(shù)只是指定了gas由誰(shuí)支付。

點(diǎn)擊CONFIRM,等待塊確認(rèn)成功之后查看合約余額和轉(zhuǎn)入地址的余額

可以看到合約eth余額已減少0.333個(gè)
https://rinkeby.etherscan.io/tx/0x63feedf866bab8dc459cc522d5cb9a0ccdbb2a58f3d83b82670352d6080306b8
這是轉(zhuǎn)入地址對(duì)應(yīng)的交易信息有興趣的可以去看看交易詳情。
總結(jié)
這塊東西在度娘沒有找到很全的相關(guān)資料,谷哥還得FQ,英語(yǔ)也不好,花了不少時(shí)間才總結(jié)出這點(diǎn)東西,肯定會(huì)有很多問(wèn)題,但也算是從頭到尾流程跑通了,不足的地方希望大家指教一起學(xué)習(xí)一起進(jìn)步。
轉(zhuǎn)載請(qǐng)注明出處,謝謝合作。