第十二課 從寵物商店案例看DAPP架構和WEB3.JS互動介面

筆名輝哥發表於2018-11-15

第十二課 從寵物商店案例看DAPP架構和WEB3.JS互動介面

1. 文章摘要

【本文目標】 瞭解ETH生態下DAPP去中心化應用程式的框架和互動流程,瞭解WEB3.JS的作用和介面函式。 【前置條件】 完成了《第六課 技術小白如何開發一個DAPP區塊鏈應用(以寵物商店為例)》的學習實踐,對智慧合約瞭解。 【技術收穫】 1). DAPP架構 2). ETH節點框架 3).寵物商店的APP.js檔案的業務處理流程圖和函式介紹 4).web3.js介面 【實操課程列表】 第一課 如何在WINDOWS環境下搭建以太坊開發環境 第二課 如何實現以太坊最簡智慧合約“Hello World”的執行 第四課 以太坊開發框架Truffle從入門到實戰 第六課 技術小白如何開發一個DAPP區塊鏈應用(以寵物商店為例) 第七課 技術小白如何在45分鐘內發行通證(TOKEN)並上線交易 第八課 如何除錯以太坊官網的智慧合約眾籌案例 第九課 如何在Remix環境下進行Solidity程式碼單步除錯 第十課 Solidity語言編輯器REMIX指導大全 第十一課 從寵物商店案例看DAPP架構和WEB3.JS互動介面

【說明】未列出的課程為知識普及的非實操類課程,所有區塊鏈文章參考“區塊鏈入口”專欄。

2. 以太坊節點和DAPP框架

2.1 以太坊節點架構

以太坊節點架構圖
以太坊是一種區塊鏈的實現。在以太坊網路中,眾多的節點彼此連線,構成了以太坊網路。 以太坊節點軟體提供兩個核心功能:資料儲存、合約程式碼執行。 在每個以太坊全節點中,都儲存有完整的區塊鏈資料。以太坊不僅將交易資料儲存在鏈上,編譯後 的合約程式碼同樣也儲存在鏈上。以太坊全節點中,同時還提供了一個虛擬機器來執行合約程式碼。

交易資料 以太坊中每筆交易都儲存在區塊鏈上。當你部署合約時,一次部署就是一筆交易。當你為候選者投票時,一次投票 又是另一筆交易。所有的這些交易都是公開的,每個人都可以看到並進行驗證。這個資料永遠也無法篡改。

為了確保網路中的所有節點都有著同一份資料拷貝,並且沒有向資料庫中寫入任何無效資料,以太坊 目前使用工作量證明POW:Proof Of Work)演算法來保證網路安全,即通過礦工挖礦(Mining)來達成共識(Consensus)—— 將資料同步到所有節點。 工作量證明不是達成共識的唯一演算法,挖礦也不是區塊鏈的唯一選擇。現在,我們只需要瞭解,共識是指各節點 的資料實現了一致,POW只是眾多用於建立共識的演算法中的一種,這種演算法需要通過礦工的挖礦來實現非可信環境下的 可信交易。共識是目的,POW是手段。 合約程式碼 以太坊不僅僅在鏈上儲存交易資料,它還可以在鏈上儲存合約程式碼。 在資料庫層面,區塊鏈的作用就是儲存交易資料。那麼給候選者投票、或者檢索投票結果的邏輯放在哪兒呢? 在以太坊的世界裡,你可以使用Solidity語言來編寫業務邏輯/應用程式碼(也就是合約:Contract), 然後將合約程式碼編譯為以太坊位元組碼,並將位元組碼部署到區塊鏈上:

image.png
編寫合約程式碼也可以使用其他的語言,不過 Solidity是到目前為止最流行的選擇。 以太坊虛擬機器 以太坊區塊鏈不僅儲存資料和程式碼,每個節點中還包含一個虛擬機器(EVM:Ethereum Virtual Machine)來執行 合約程式碼 —— 聽起來就像計算機作業系統。 事實上,這一點是以太坊區別於比特幣(Bitcoin)的最核心的一點:虛擬機器的存在使區塊鏈邁入了2.0 時代,也讓區塊鏈第一次成為應用開發者友好的平臺。

##2.2 DAPP架構 下圖給出了基於以太坊的去中心化應用架構:

DAPP架構圖
每個客戶端(瀏覽器)都是與各自的節點應用例項進行互動,而不是向 一箇中心化的伺服器請求服務。 在一個理想的去中心化環境中,每個想要跟DApp互動的人,都需要在他們的計算機或手機上面執行 一個的完整區塊鏈節點 —— 簡言之,每個人都執行一個全節點。這意味著,在能夠真正使用一個 去中心化應用之前,使用者不得不下載整個區塊鏈。 不過我們並非生活在一個烏托邦裡,期待每個使用者都先執行一個全節點,然後再使用你的應用是不現實的。 但是去中心化背後的核心思想,就是不依賴於中心化的伺服器。所以,區塊鏈社群已經出現了 一些解決方案,例如提供公共區塊鏈節點的Infura, 以及瀏覽器外掛Metamask等。通過這些方案, 你就不需要花費大量的硬碟、記憶體和時間去下載並執行完整的區塊鏈節點,同時也可以利用去中心化 的優點。

Web3.js是以太坊官方的Javascript API,可以幫助智慧合約開發者使用HTTP或者IPC與本地的或者遠端的以太坊節點互動。實際上就是一個庫的集合,主要包括下面幾個庫:

  • web3-eth用來與以太坊區塊鏈和智慧合約互動
  • web3-shh用來控制whisper協議與p2p通訊以及廣播
  • web3-bzz用來與swarm協議互動
  • web3-utils包含了一些Dapp開發有用的功能

Web3與geth通訊使用的是 JSON-RPC ,這是一種輕量級的RPC(Remote Procedure Call)協議,整個通訊的模型可以抽象為下圖。

歐陽哥哥分享的WEB3位置圖

#3. 以寵物商店為例WEB3.JS程式碼 第六課 技術小白如何開發一個DAPP區塊鏈應用(以寵物商店為例) 這篇文章詳細介紹了一個寵物商店DAPP的案例。本節重點分析引用WEB3.JS相關介面程式碼。

##3.1 加註釋的app.js程式碼

App = {
  web3Provider: null,
  contracts: {},

  init: function() {
  	/*載入寵物名字,圖片,年齡,位置等資訊*/
    // Load pets.
    $.getJSON('../pets.json', function(data) {
      var petsRow = $('#petsRow');
      var petTemplate = $('#petTemplate');

      for (i = 0; i < data.length; i ++) {
        petTemplate.find('.panel-title').text(data[i].name);
        petTemplate.find('img').attr('src', data[i].picture);
        petTemplate.find('.pet-breed').text(data[i].breed);
        petTemplate.find('.pet-age').text(data[i].age);
        petTemplate.find('.pet-location').text(data[i].location);
        petTemplate.find('.btn-adopt').attr('data-id', data[i].id);

        petsRow.append(petTemplate.html());
      }
    });

    return App.initWeb3();
  },

  initWeb3: function() {
  	/*如果web3事先被定義,則使用當前web3例項的錢包物件。例如remix下JavaScript VM建立的虛擬錢包(有4個含100個 ETH的賬戶);
  	  或者MetaMask連結後的賬戶錢包;或者mist錢包*/
    if (typeof web3 !== 'undefined') {
      App.web3Provider = web3.currentProvider;
    } else {
      // If no injected web3 instance is detected, fall back to Ganache
      /*如果web3不存在,則啟動本地啟動的Ganache錢包。[前提:要啟動好本地的Ganache環境哦,否則會建立不成功]*/
      App.web3Provider = new Web3.providers.HttpProvider('http://localhost:7545');
    }
    /*建立Web3例項,入口引數為剛才配置的App.web3Provider*/
    web3 = new Web3(App.web3Provider);

    /*呼叫初始化合約函式*/
    return App.initContract();
  },

  initContract: function() {
  	/*參考 http://www.w3school.com.cn/jquery/ajax_getjson.asp 獲取getJSON到的方法*/
    $.getJSON('Adoption.json', function(data) {
      // Get the necessary contract artifact file and instantiate it with truffle-contract
      var AdoptionArtifact = data;
      App.contracts.Adoption = TruffleContract(AdoptionArtifact);
    
      // 設定當前合約的web3Provider錢包提供者
      App.contracts.Adoption.setProvider(App.web3Provider);
    
      // 使用我們的合約去提取和標識已領養的寵物
      return App.markAdopted();
    });

		/*返回繫結事件*/
    return App.bindEvents();
  },

  /*點選含有'.btn-adopt'類的click事件會觸發handleAdopt(處理領養)的函式*/
  bindEvents: function() {
    $(document).on('click', '.btn-adopt', App.handleAdopt);
  },

 /*如果該寵物已被領養,則文字顯示為"Success",按鈕不可點選*/
  markAdopted: function(adopters, account) {
    var adoptionInstance;

    App.contracts.Adoption.deployed().then(function(instance) {
      adoptionInstance = instance;
    
      return adoptionInstance.getAdopters.call();
    }).then(function(adopters) {
      for (i = 0; i < adopters.length; i++) {
      	/*如果領養者的地址不是為0,則設定按鈕字型和狀態,*/
        if (adopters[i] !== '0x0000000000000000000000000000000000000000') {
          $('.panel-pet').eq(i).find('button').text('Success').attr('disabled', true);
        }
      }
    }).catch(function(err) {
      console.log(err.message);
    });
  },

  handleAdopt: function(event) {
    event.preventDefault();
    
    /*parseInt() 函式可解析一個字串,並返回一個整數。*/
    var petId = parseInt($(event.target).data('id'));

    var adoptionInstance;
    
    /*獲取當前ETH錢包的賬號*/
    web3.eth.getAccounts(function(error, accounts) {
      if (error) {
        console.log(error);
      }
    
     /*取第一個錢包賬號*/
      var account = accounts[0];
    
     /*ES6的then函式呼叫,鏈式呼叫*/
      App.contracts.Adoption.deployed().then(function(instance) {
        adoptionInstance = instance;

        // 通過傳送賬戶執行adopt領養函式的交易的返回值
        // 此處沒有搞懂,智慧合約Adoption.adopt只有一個入參,此處為什麼增加了第二個{from: account}引數呢?
        //TINY熊認為,把它當做語法就可以, 要麼提前設定預設賬號, 要麼呼叫時指定
        return adoptionInstance.adopt(petId, {from: account});
      }).then(function(result) {
      	/*標識領養狀態*/
        return App.markAdopted();
        /*輸出錯誤*/
      }).catch(function(err) {
        console.log(err.message);
      });
    });
  }

};

/*視窗載入即呼叫App.init函式*/
$(function() {
  $(window).load(function() {
    App.init();
  });
});


複製程式碼

##3.2 app.js呼叫WEB3流程分析

app.js呼叫WEB3流程圖

#4. Web3 JavaScript app API 參考 Web3的官網文件給出了詳細的介面文件和說明。

web3

web3物件提供了所有方法。

示例:

//初始化過程
var Web3 = require('web3');

if (typeof web3 !== 'undefined') {
  web3 = new Web3(web3.currentProvider);
} else {
  // set the provider you want from Web3.providers
  web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
}

複製程式碼

web3.version.api

web3.version.api

返回值:

String - 以太坊js的api版本

示例:

//省略初始化過程
var version = web3.version.api;
console.log(version);

$ node test.js
0.18.2

複製程式碼

web3.version.node

同步方式:

web3.verison.node

非同步方式:

web3.version.getNode(callback(error, result){ ... })

返回值:

String - 客戶端或節點的版本資訊

示例:

//省略初始化過程
var version = web3.version.node;
console.log(version);

$ node test.js
EthereumJS TestRPC/v3.0.3/ethereum-js

複製程式碼

web3.version.network

同步方式:

web3.version.network

非同步方式:

web3.version.getNetwork(callback(error, result){ ... })

返回值:

String - 網路協議版本

示例:

//省略初始化過程
var version = web3.version.network;
console.log(version);

$ node test.js
1488546587563

複製程式碼

web3.version.ethereum

同步方式:

web3.version.ethereum

非同步方式:

web3.version.getEthereum(callback(error, result){ ... })

返回值:

String - 以太坊的協議版本

示例:

//省略初始化過程
var version = web3.version.ethereum;
console.log(version);

$ node test.js
60

複製程式碼

注意:EthereumJS testRPC客戶端不支援這個命令,報錯Error: Error: RPC method eth_protocolVersion not supported.

web3.version.whisper

同步方式:

web3.version.whisper

非同步方式:

web3.version.getWhisper(callback(error, result){ ... })

返回值:

String - whisper協議的版本

示例:

//省略初始化過程
var version = web3.version.whisper;
console.log(version);

$ node test.js
20

複製程式碼

注意:EthereumJS testRPC客戶端不支援這個命令,報錯Error: Error: RPC method shh_version not supported.

web3.isConnected

web3.isConnected

可以用來檢查到節點的連線是否存在(connection to node exist)。

引數:

返回值:

Boolean

示例:

//省略初始化過程
var connected = web3.isConnected();
if(!connected){
  console.log("node not connected!");
}else{
  console.log("node connected");
}

複製程式碼

web3.setProvider

web3.setProvider

設定Provider

引數:

返回值:

undefined

示例:

web3.setProvider(new web3.providers.HttpProvider('http://localhost:8545'));

複製程式碼

web3.currentProvider

web3.currentProvider

如果已經設定了Provider,則返回當前的Provider。這個方法可以用來檢查在使用mist瀏覽器等情況下已經設定過Provider,避免重複設定的情況。

返回值:

Object - null 或 已經設定的Provider

示例:

if(!web3.currentProvider)
    web3.setProvider(new web3.providers.HttpProvider("http://localhost:8545"));

複製程式碼

web3.reset

web3.reset

用來重置web3的狀態。重置除了manager以外的其它所有東西。解除安裝filter,停止狀態輪詢。

引數:

  1. Boolean - 如果設定為true,將會解除安裝所有的filter,但會保留web3.eth.isSyncing()的狀態輪詢。

返回值:

undefined

示例:

//省略初始化過程
console.log("reseting ... ");
web3.reset();
console.log("is connected:" + web3.isConnected());

$ node test.js
reseting ...
is connected:true

複製程式碼

web3.sha3

web3.sha3(string, options)

引數:

  1. String - 傳入的需要使用Keccak-256 SHA3演算法進行雜湊運算的字串。
  2. Object - 可選項設定。如果要解析的是hex格式的十六進位制字串。需要設定encodinghex。因為JS中會預設忽略0x

返回值:

String - 使用Keccak-256 SHA3演算法雜湊過的結果。

示例:

//省略初始化過程
var hash = web3.sha3("Some string to be hashed");
console.log(hash); 
var hashOfHash = web3.sha3(hash, {encoding: 'hex'});
console.log(hashOfHash); 

複製程式碼

web3.toHex

web3.toHex

將任何值轉為HEX

引數:

  1. String|Number|Object|Array|BigNumber - 需要轉化為HEX的值。如果是一個物件或陣列型別,將會先用JSON.stringify1進行轉換成字串。如果傳入的是BigNumber2,則將得到對應的NumberHEX

示例:

//初始化基本物件
var Web3 = require('web3');
var web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
var BigNumber = require('bignumber.js');

var str = "abcABC";
var obj = {abc: 'ABC'};
var bignumber = new BigNumber('12345678901234567890');

var hstr = web3.toHex(str);
var hobj = web3.toHex(obj);
var hbg = web3.toHex(bignumber);

console.log("Hex of Sring:" + hstr);
console.log("Hex of Object:" + hobj);
console.log("Hex of BigNumber:" + hbg);

$ node test.js
Hex of Sring:0x616263414243
Hex of Object:0x7b22616263223a22414243227d
Hex of BigNumber:0xab54a98ceb1f0ad2

複製程式碼

web3.toAscii

web3.toAscii(hexString)

HEX字串轉為ASCII3字串

引數:

  1. String - 十六進位制字串。

返回值:

String - 給定十六進位制字串對應的ASCII碼值。

示例:

var str = web3.toAscii("0x657468657265756d000000000000000000000000000000000000000000000000");
console.log(str); // "ethereum"

複製程式碼

web3.fromAscii

web3.fromAscii

將任何的ASCII碼字串轉為HEX字串。

引數:

  1. String - ASCII碼字串
  2. Number - 返回的字串位元組大小,不夠長會自動填充。

返回值:

String - 轉換後的HEX字串。

示例:

var str = web3.fromAscii('ethereum');
console.log(str); // "0x657468657265756d"

var str2 = web3.fromAscii('ethereum', 32);
console.log(str2); // "0x657468657265756d000000000000000000000000000000000000000000000000"

$ node test.js
0x657468657265756d
0x657468657265756d

複製程式碼

備註: 填充padding功能好像不可用4

web3.toDecimal

web3.toDecimal

將一個十六進位制轉為一個十進位制的數字

引數:

  1. String - 十六進位制字串

返回:

Number - 傳入字串所代表的十六進位制值。

示例:

var number = web3.toDecimal('0x15');
console.log(number); // 21

複製程式碼

web3.fromDecimal

web3.fromDecimal

將一個數字,或者字串形式的數字轉為一個十六進位制串。

引數:

  1. Number|String - 數字

返回值:

String - 給定數字對應的十六進位制表示。

示例:

var value = web3.fromDecimal('21');
console.log(value); // "0x15"

複製程式碼

web3.fromWei

web3.fromWei(number, 單位)

以太坊貨幣單位之間的轉換。將以wei為單位的數量,轉為下述的單位,可取值如下:

  • kwei/ada
  • mwei/babbage
  • gwei/shannon
  • szabo
  • finney
  • ether
  • kether/grand/einstein
  • mether
  • gether
  • tether

引數:

  1. Number|String|BigNumber - 數字或BigNumber
  2. String - 單位字串

返回值:

String|BigNumber - 根據傳入引數的不同,分別是字串形式的字串,或者是BigNumber

示例:

var value = web3.fromWei('21000000000000', 'finney');
console.log(value); // "0.021"

複製程式碼

web3.toWei

web3.toWei(number, 單位)

按對應貨幣轉為以wei為單位。可選擇的單位如下:

  • kwei/ada
  • mwei/babbage
  • gwei/shannon
  • szabo
  • finney
  • ether
  • kether/grand/einstein
  • mether
  • gether
  • tether

引數:

  1. Number|String|BigNumber - 數字或BigNumber
  2. String - 字串單位

返回值:

String|BigNumber - 根據傳入引數的不同,分別是字串形式的字串,或者是BigNumber

示例:

var value = web3.toWei('1', 'ether');
console.log(value); // "1000000000000000000"

複製程式碼

web3.toBigNumber

web3.toBigNumber(數字或十六進位制字串)

將給定的數字或十六進位制字串轉為BigNumber5

引數:

  1. Number|String - 數字或十六進位制格式的數字

返回值:

BigNumber - BigNumber的例項

示例:

var value = web3.toBigNumber('200000000000000000000001');
console.log(value); // instanceOf BigNumber
console.log(value.toNumber()); // 2.0000000000000002e+23
console.log(value.toString(10)); // '200000000000000000000001'

複製程式碼

web3.net

web3.net.listening

同步方式:

web3.net.listening

非同步方式:

web3.net.getListener(callback(error, result){ ... })

此屬性是隻讀的,表示當前連線的節點,是否正在listen網路連線與否。listen可以理解為接收。

返回值:

Boolean - true表示連線上的節點正在listen網路請求,否則返回false

示例:

var listening = web3.net.listening;
console.log("client listening: " + listening);

$ node test.js
client listening: true

複製程式碼

備註: 如果關閉我們要連線的測試節點,會報錯Error: Invalid JSON RPC response: undefined。所以這個方法返回的是我們連上節點的listen狀態。

web3.net.peerCount

同步方式:

web3.net.peerCount

非同步方式:

web3.net.getPeerCount(callback(error, result){ ... })

屬性是隻讀的,返回連線節點已連上的其它以太坊節點的數量。

返回值:

Number - 連線節點連上的其它以太坊節點的數量

示例:

var peerCount = web3.net.peerCount;
console.log("Peer count: " + peerCount); 

$ node test.js
Peer count: 0

複製程式碼

web3.eth

包含以太坊區塊鏈相關的方法

示例:

var eth = web3.eth;

複製程式碼

web3.eth.defaultAccount

web3.eth.defaultAccount

預設的地址在使用下述方法時使用,你也可以選擇通過指定from屬性,來覆蓋這個預設設定。

  • web3.eth.sendTransaction()
  • web3.eth.call()

預設值為undefined,20位元組大小,任何你有私匙的你自己的地址。

返回值:

String - 20位元組的當前設定的預設地址。

示例:

console.log("Current default: " + web3.eth.defaultAccount);
web3.eth.defaultAccount = '0x8888f1f195afa192cfee860698584c030f4c9db1';
console.log("Current default: " + web3.eth.defaultAccount);

$ node test.js
Current default: undefined
Current default: 0x8888f1f195afa192cfee860698584c030f4c9db1

複製程式碼

web3.eth.defaultBlock

web3.eth.defaultBlock

使用下述方法時,會使用預設塊設定,你也可以通過傳入defaultBlock來覆蓋預設配置。

  • web3.eth.getBalance()
  • web3.eth.getCode()
  • web3.eth.getTransactionCount()
  • web3.eth.getStorageAt()
  • web3.eth.call()
  • contract.myMethod.call()
  • contract.myMethod.estimateGas()

可選的塊引數,可能下述值中的一個:

  • Number - 區塊號
  • String - earliest,創世塊。
  • String - latest,最近剛出的最新塊,當前的區塊頭。
  • String - pending,當前正在mine的區塊,包含正在打包的交易。

預設值是latest

返回值:

Number|String - 預設要查狀態的區塊號。

示例:

console.log("defaultBlock: " + web3.eth.defaultBlock);
web3.eth.defaultBlock = 231;
console.log("defaultBlock: " + web3.eth.defaultBlock);

$ node test.js
defaultBlock: latest
defaultBlock: 231

複製程式碼

web3.eth.syncing

同步方式:

web3.eth.syncing

非同步方式:

web3.eth.getSyncing(callback(error, result){ ... })

這個屬性是隻讀的。如果正在同步,返回同步物件。否則返回false

返回值:

Object|Boolean - 如果正在同步,返回含下面屬性的同步物件。否則返回false

返回值:

  • startingBlockNumber - 同步開始區塊號
  • currentBlock: Number - 節點當前正在同步的區塊號
  • highestBlock: Number - 預估要同步到的區塊
var sync = web3.eth.syncing;
console.log(sync);

$ node test.js
false
//正在sync的情況
$ node test.js
{
   startingBlock: 300,
   currentBlock: 312,
   highestBlock: 512
}

複製程式碼

web3.eth.isSyncing

web3.eth.isSyncing(callback)

提供同步開始,更新,停止的回撥函式方法。

返回值:

Object - 一個syncing物件,有下述方法:

  • syncing.addCallback(): 增加另一個回撥函式,在節點開始或停止呼叫時進行呼叫。
  • syncing.stopWatching(): 停止同步回撥。

回撥返回值:

  • Boolean - 同步開始時,此值為true,同步停止時此回撥值為false
  • Object - 當正在同步時,會返回同步物件。
    • startingBlockNumber - 同步開始區塊號
    • currentBlock: Number - 節點當前正在同步的區塊號
    • highestBlock: Number - 預估要同步到的區塊

示例:

//初始化基本物件
var Web3 = require('web3');
var web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
var BigNumber = require('bignumber.js');

web3.eth.isSyncing(function(error, sync){
    if(!error) {
        // stop all app activity
        if(sync === true) {
           // we use `true`, so it stops all filters, but not the web3.eth.syncing polling
           web3.reset(true);

        // show sync info
        } else if(sync) {
           console.log(sync.currentBlock);

        // re-gain app operation
        } else {
            // run your app init function...
        }
    }
});

複製程式碼

web3.eth.coinbase

同步方式:

web3.eth.coinbase

非同步方式:

web3.eth.getCoinbase(callback(error, result){ ... })

只讀屬性,節點配置的,如果挖礦成功獎勵的地址。

返回值:

String - 節點的挖礦獎勵地址。

示例:

var coinbase = web3.eth.coinbase;
console.log(coinbase); // "0x407d73d8a49eeb85d32cf465507dd71d507100c1"

複製程式碼

web3.eth.mining

同步方式:

web3.eth.mining

非同步方式:

web3.eth.getMining(callback(error, result){ ... })

屬性只讀,表示該節點是否配置挖礦。

返回值:

Boolean - true 表示配置挖礦,否則表示沒有。

var mining = web3.eth.mining;
console.log(mining); // true or false

複製程式碼

web3.eth.hashrate

同步方式:

web3.eth.hashrate

非同步方式:

web3.eth.getHashrate(callback(error, result){ ... })

屬性只讀,表示的是當前的每秒的雜湊難度。

返回值:

Number - 每秒的雜湊數

示例:

var hashrate = web3.eth.hashrate;
console.log(hashrate);

複製程式碼

web3.eth.gasPrice

同步方式:

web3.eth.gasPrice

非同步方式:

web3.eth.getGasPrice(callback(error, result){ ... })

屬性是隻讀的,返回當前的gas價格。這個值由最近幾個塊的gas價格的中值6決定。

返回值:

BigNumber - 當前的gas價格的BigNumber例項,以wei為單位。

var gasPrice = web3.eth.gasPrice;
console.log(gasPrice.toString(10)); // "10000000000000"

複製程式碼

web3.eth.accounts

同步方式:

web3.eth.accounts

非同步方式:

web3.eth.getAccounts(callback(error, result){ ... })

只讀屬性,返回當前節點持有的帳戶列表。

返回值:

Array - 節點持有的帳戶列表。

示例:

var accounts = web3.eth.accounts;
console.log(accounts); 

複製程式碼

web3.eth.blockNumber

同步方式:

web3.eth.blockNumber

非同步方式:

web3.eth.getBlockNumber(callback(error, result){ ... })

屬性只讀,返回當前區塊號。

var number = web3.eth.blockNumber;
console.log(number); // 2744

複製程式碼

web3.eth.register

web3.eth.register(addressHexString [, callback])

(暫未實現)將給定地址註冊到web3.eth.accounts。這將允許無私匙的帳戶,如合約被關聯到有私匙的帳戶,如合約錢包。

引數:

  • String - 要註冊的地址。
  • Function -(可選)回撥函式,用於支援非同步的方式執行7

返回值:

待確定

示例:

web3.eth.register("0x407d73d8a49eeb85d32cf465507dd71d507100ca")

複製程式碼

web3.eth.unRegister

非同步方式

web3.eth.unRegister(addressHexString [, callback])

(暫未實現)取消註冊給定地址

引數:

  • String - 要取消註冊的地址
  • Function - (可選) 回撥函式,用於支援非同步的方式執行7

返回值:

待確定

示例:

web3.eth.unRegister("0x407d73d8a49eeb85d32cf465507dd71d507100ca")

複製程式碼

web3.eth.getBalance

web3.eth.getBalance(addressHexString [, defaultBlock] [, callback])

獲得在指定區塊時給定地址的餘額。

引數:

  • String - 要查詢餘額的地址。
  • Number|String -(可選)如果不設定此值使用web3.eth.defaultBlock設定的塊,否則使用指定的塊。
  • Funciton - (可選)回撥函式,用於支援非同步的方式執行7

返回值:

String - 一個包含給定地址的當前餘額的BigNumber例項,單位為wei

示例:

var balance = web3.eth.getBalance("0x407d73d8a49eeb85d32cf465507dd71d507100c1");
console.log(balance); // instanceof BigNumber
console.log(balance.toString(10)); // '1000000000000'
console.log(balance.toNumber()); // 1000000000000

複製程式碼

web3.eth.getStorageAt

web3.eth.getStorageAt(addressHexString, position [, defaultBlock] [, callback])

獲得某個地址指定位置的儲存的狀態值。

合約由控制執行的EVM位元組碼和用來儲存狀態的Storage兩部分組成。Storage在區塊鏈上是以均為32位元組的鍵,值對的形式進行儲存8

引數:

  • String - 要獲得儲存的地址。
  • Number - 要獲得的儲存的序號
  • Number|String -(可選)如果未傳遞引數,預設使用web3.eth.defaultBlock定義的塊,否則使用指定區塊。
  • Function - 回撥函式,用於支援非同步的方式執行7

返回值:

String - 給定位置的儲存值

示例:

var state = web3.eth.getStorageAt("0x407d73d8a49eeb85d32cf465507dd71d507100c1", 0);
console.log(state); // "0x03"

複製程式碼

web3.eth.getCode

web3.eth.getCode(addressHexString [, defaultBlock] [, callback])

獲取指定地址的程式碼

引數:

  • String - 要獲得程式碼的地址。
  • Number|String -(可選)如果未傳遞引數,預設使用web3.eth.defaultBlock定義的塊,否則使用指定區塊。
  • Function - 回撥函式,用於支援非同步的方式執行7

返回值:

String - 給定地址合約編譯後的位元組程式碼。

示例:

var code = web3.eth.getCode("0xd5677cf67b5aa051bb40496e68ad359eb97cfbf8");
console.log(code); // "0x600160008035811a818181146012578301005b601b6001356025565b8060005260206000f25b600060078202905091905056"

複製程式碼

web3.eth.getBlock

web3.eth.getBlock(blockHashOrBlockNumber [, returnTransactionObjects] [, callback])

返回塊號或區塊雜湊值所對應的區塊

引數:

  • Number|String -(可選)如果未傳遞引數,預設使用web3.eth.defaultBlock定義的塊,否則使用指定區塊。
  • Boolean -(可選)預設值為falsetrue會將區塊包含的所有交易作為物件返回。否則只返回交易的雜湊。
  • Function - 回撥函式,用於支援非同步的方式執行7

返回值 - 區塊物件:

  • Number - 區塊號。當這個區塊處於pending將會返回null
  • hash - 字串,區塊的雜湊串。當這個區塊處於pending將會返回null
  • parentHash - 字串,32位元組的父區塊的雜湊值。
  • nonce - 字串,8位元組。POW生成的雜湊。當這個區塊處於pending將會返回null
  • sha3Uncles - 字串,32位元組。叔區塊的雜湊值。
  • logsBloom - 字串,區塊日誌的布隆過濾器9。當這個區塊處於pending將會返回null
  • transactionsRoot - 字串,32位元組,區塊的交易字首樹的根。
  • stateRoot - 字串,32位元組。區塊的最終狀態字首樹的根。
  • miner - 字串,20位元組。這個區塊獲得獎勵的礦工。
  • difficulty - BigNumber型別。當前塊的難度,整數。
  • totalDifficulty - BigNumber型別。區塊鏈到當前塊的總難度,整數。
  • extraData - 字串。當前塊的extra data欄位。
  • size - Number。當前這個塊的位元組大小。
  • gasLimit - Number,當前區塊允許使用的最大gas
  • gasUsed - 當前區塊累計使用的總的gas
  • timestamp - Number。區塊打包時的unix時間戳。
  • transactions - 陣列。交易物件。或者是32位元組的交易雜湊。
  • uncles - 陣列。叔雜湊的陣列。

示例:

var info = web3.eth.getBlock(3150);
console.log(info);
/*
{
  "number": 3,
  "hash": "0xef95f2f1ed3ca60b048b4bf67cde2195961e0bba6f70bcbea9a2c4e133e34b46",
  "parentHash": "0x2302e1c0b972d00932deb5dab9eb2982f570597d9d42504c05d9c2147eaf9c88",
  "nonce": "0xfb6e1a62d119228b",
  "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
  "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  "transactionsRoot": "0x3a1b03875115b79539e5bd33fb00d8f7b7cd61929d5a3c574f507b8acf415bee",
  "stateRoot": "0xf1133199d44695dfa8fd1bcfe424d82854b5cebef75bddd7e40ea94cda515bcb",
  "miner": "0x8888f1f195afa192cfee860698584c030f4c9db1",
  "difficulty": BigNumber,
  "totalDifficulty": BigNumber,
  "size": 616,
  "extraData": "0x",
  "gasLimit": 3141592,
  "gasUsed": 21662,
  "timestamp": 1429287689,
  "transactions": [
    "0x9fc76417374aa880d4449a1f7f31ec597f00b1f6f3dd2d66f4c9c6c445836d8b"
  ],
  "uncles": []
}
*/

複製程式碼

web3.eth.getBlockTransactionCount

web3.eth.getBlockTransactionCount(hashStringOrBlockNumber [, callback])

返回指定區塊的交易數量。

引數:

  • Number|String -(可選)如果未傳遞引數,預設使用web3.eth.defaultBlock定義的塊,否則使用指定區塊。
  • Function - 回撥函式,用於支援非同步的方式執行7

返回值:

Nubmer - 給定區塊的交易數量。

示例:

var number = web3.eth.getBlockTransactionCount("0x407d73d8a49eeb85d32cf465507dd71d507100c1");
console.log(number); // 1

複製程式碼

web3.eth.getUncle

web3.eth.getUncle(blockHashStringOrNumber, uncleNumber [, returnTransactionObjects] [, callback])

通過指定叔位置,返回指定叔塊。

引數:

  • Number|String -(可選)如果未傳遞引數,預設使用web3.eth.defaultBlock定義的塊,否則使用指定區塊。
  • Number - 叔的序號。
  • Boolean -(可選)預設值為falsetrue會將區塊包含的所有交易作為物件返回。否則只返回交易的雜湊。
  • Function - 回撥函式,用於支援非同步的方式執行7

返回值:

Object - 返回的叔塊。返回值參考web3.eth.getBlock()

備註: 叔塊沒有自己的交易資料。

示例:

var uncle = web3.eth.getUncle(500, 0);
console.log(uncle); // see web3.eth.getBlock

複製程式碼

web3.eth.getTransaction

web3.eth.getTransaction(transactionHash [, callback])

返回匹配指定交易雜湊值的交易。

引數:

  • String - 交易的雜湊值。
  • Function - 回撥函式,用於支援非同步的方式執行7

返回值:

Object - 一個交易物件

  • hash: String - 32位元組,交易的雜湊值。
  • nonce: Number - 交易的發起者在之前進行過的交易數量。
  • blockHash: String - 32位元組。交易所在區塊的雜湊值。當這個區塊處於pending將會返回null
  • blockNumber: Number - 交易所在區塊的塊號。當這個區塊處於pending將會返回null
  • transactionIndex: Number - 整數。交易在區塊中的序號。當這個區塊處於pending將會返回null
  • from: String - 20位元組,交易發起者的地址。
  • to: String - 20位元組,交易接收者的地址。當這個區塊處於pending將會返回null
  • value: BigNumber - 交易附帶的貨幣量,單位為Wei
  • gasPrice: BigNumber - 交易發起者配置的gas價格,單位是wei
  • gas: Number - 交易發起者提供的gas。.
  • input: String - 交易附帶的資料。

示例:

var blockNumber = 668;
var indexOfTransaction = 0

var transaction = web3.eth.getTransaction(blockNumber, indexOfTransaction);
console.log(transaction);
/*
{
  "hash": "0x9fc76417374aa880d4449a1f7f31ec597f00b1f6f3dd2d66f4c9c6c445836d8b",
  "nonce": 2,
  "blockHash": "0xef95f2f1ed3ca60b048b4bf67cde2195961e0bba6f70bcbea9a2c4e133e34b46",
  "blockNumber": 3,
  "transactionIndex": 0,
  "from": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
  "to": "0x6295ee1b4f6dd65047762f924ecd367c17eabf8f",
  "value": BigNumber,
  "gas": 314159,
  "gasPrice": BigNumber,
  "input": "0x57cb2fc4"
}
*/

複製程式碼

web3.eth.getTransactionFromBlock

getTransactionFromBlock(hashStringOrNumber, indexNumber [, callback])

複製程式碼

返回指定區塊的指定序號的交易。

引數:

  • String - 區塊號或雜湊。或者是earliestlatestpending。檢視web3.eth.defaultBlock瞭解可選值。
  • Number - 交易的序號。
  • Function - 回撥函式,用於支援非同步的方式執行7

返回值:

Object - 交易物件,詳見web3.eth.getTransaction

示例:

var transaction = web3.eth.getTransactionFromBlock('0x4534534534', 2);
console.log(transaction); // see web3.eth.getTransaction

複製程式碼

web3.eth.getTransactionReceipt

web3.eth.getTransactionReceipt(hashString [, callback])

通過一個交易雜湊,返回一個交易的收據。

備註:處於pending狀態的交易,收據是不可用的。

引數:

  • String - 交易的雜湊
  • Function - 回撥函式,用於支援非同步的方式執行7

返回值:

Object - 交易的收據物件,如果找不到返回null

  • blockHash: String - 32位元組,這個交易所在區塊的雜湊。
  • blockNumber: Number - 交易所在區塊的塊號。
  • transactionHash: String - 32位元組,交易的雜湊值。
  • transactionIndex: Number - 交易在區塊裡面的序號,整數。
  • from: String - 20位元組,交易傳送者的地址。
  • to: String - 20位元組,交易接收者的地址。如果是一個合約建立的交易,返回null
  • cumulativeGasUsed: Number - 當前交易執行後累計花費的gas總值10
  • gasUsed: Number - 執行當前這個交易單獨花費的gas
  • contractAddress: String - 20位元組,建立的合約地址。如果是一個合約建立交易,返回合約地址,其它情況返回null
  • logs: Array - 這個交易產生的日誌物件陣列。

示例:

var receipt = web3.eth.getTransactionReceipt('0x9fc76417374aa880d4449a1f7f31ec597f00b1f6f3dd2d66f4c9c6c445836d8b');
console.log(receipt);
{
  "transactionHash": "0x9fc76417374aa880d4449a1f7f31ec597f00b1f6f3dd2d66f4c9c6c445836d8b",
  "transactionIndex": 0,
  "blockHash": "0xef95f2f1ed3ca60b048b4bf67cde2195961e0bba6f70bcbea9a2c4e133e34b46",
  "blockNumber": 3,
  "contractAddress": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
  "cumulativeGasUsed": 314159,
  "gasUsed": 30234,
  "logs": [{
         // logs as returned by getFilterLogs, etc.
     }, ...]
}

複製程式碼

web3.eth.getTransactionCount

web3.eth.getTransactionCount(addressHexString [, defaultBlock] [, callback])

返回指定地址發起的交易數。

引數:

  • String - 要獲得交易數的地址。
  • Number|String -(可選)如果未傳遞引數,預設使用web3.eth.defaultBlock定義的塊,否則使用指定區塊。
  • Function - 回撥函式,用於支援非同步的方式執行7

返回值:

Number - 指定地址傳送的交易數量。

示例:

var number = web3.eth.getTransactionCount("0x407d73d8a49eeb85d32cf465507dd71d507100c1");
console.log(number); // 1

複製程式碼

web3.eth.sendTransaction

web3.eth.sendTransaction(transactionObject [, callback])

傳送一個交易到網路。

引數:

  • Object - 要傳送的交易物件。
    • from: String - 指定的傳送者的地址。如果不指定,使用web3.eth.defaultAccount
    • to: String - (可選)交易訊息的目標地址,如果是合約建立,則不填.
    • value: Number|String|BigNumber - (可選)交易攜帶的貨幣量,以wei為單位。如果合約建立交易,則為初始的基金。
    • gas: Number|String|BigNumber - (可選)預設是自動,交易可使用的gas,未使用的gas會退回。
    • gasPrice: Number|String|BigNumber - (可選)預設是自動確定,交易的gas價格,預設是網路gas價格的平均值 。
    • data: String - (可選)或者包含相關資料的位元組字串,如果是合約建立,則是初始化要用到的程式碼。
    • nonce: Number - (可選)整數,使用此值,可以允許你覆蓋你自己的相同nonce的,正在pending中的交易11
  • Function - 回撥函式,用於支援非同步的方式執行7

返回值:

String - 32位元組的交易雜湊串。用16進製表示。

如果交易是一個合約建立,請使用web3.eth.getTransactionReceipt()在交易完成後獲取合約的地址。

示例:

// compiled solidity source code using https://chriseth.github.io/cpp-ethereum/
var code = "603d80600c6000396000f3007c01000000000000000000000000000000000000000000000000000000006000350463c6888fa18114602d57005b6007600435028060005260206000f3";

web3.eth.sendTransaction({data: code}, function(err, address) {
  if (!err)
    console.log(address); // "0x7f9fade1c0d57a7af66ab4ead7c2eb7b11a91385"
});

複製程式碼

web3.eth.sendRawTransaction

web3.eth.sendRawTransaction(signedTransactionData [, callback])

傳送一個已經簽名的交易。比如可以用下述簽名的例子:github.com/SilentCicer…

引數:

  • String - 16進位制格式的簽名交易資料。
  • Function - 回撥函式,用於支援非同步的方式執行7

返回值:

String - 32位元組的16進位制格式的交易雜湊串。

如果交易是一個合約建立,請使用web3.eth.getTransactionReceipt()在交易完成後獲取合約的地址。

示例:

var Tx = require('ethereumjs-tx');
var privateKey = new Buffer('e331b6d69882b4cb4ea581d88e0b604039a3de5967688d3dcffdd2270c0fd109', 'hex')

var rawTx = {
  nonce: '0x00',
  gasPrice: '0x09184e72a000', 
  gasLimit: '0x2710',
  to: '0x0000000000000000000000000000000000000000', 
  value: '0x00', 
  data: '0x7f7465737432000000000000000000000000000000000000000000000000000000600057'
}

var tx = new Tx(rawTx);
tx.sign(privateKey);

var serializedTx = tx.serialize();

//console.log(serializedTx.toString('hex'));
//0xf889808609184e72a00082271094000000000000000000000000000000000000000080a47f74657374320000000000000000000000000000000000000000000000000000006000571ca08a8bbf888cfa37bbf0bb965423625641fc956967b81d12e23709cead01446075a01ce999b56a8a88504be365442ea61239198e23d1fce7d00fcfc5cd3b44b7215f

web3.eth.sendRawTransaction(serializedTx.toString('hex'), function(err, hash) {
  if (!err)
    console.log(hash); // "0x7f9fade1c0d57a7af66ab4ead79fade1c0d57a7af66ab4ead7c2c2eb7b11a91385"
});

複製程式碼

web3.eth.sign

web3.eth.sign(address, dataToSign, [, callback])

使用指定帳戶簽名要傳送的資料,帳戶需要處於unlocked狀態。

引數:

  • String - 簽名使用的地址
  • String - 要簽名的資料
  • Function -(可選)回撥函式,用於支援非同步的方式執行7

返回值:

String - 簽名後的資料。

返回的值對應的是ECDSA(Elliptic Curve Digital Signature Algorithm)12簽名後的字串。

r = signature[0:64]
s = signature[64:128]
v = signature[128:130]

複製程式碼

需要注意的是,如果你使用ecrecover,這裡的v值是0001,所以如果你想使用他們,你需要把這裡的v值轉成整數,再加上27。最終你要用的值將是272813

示例:

var result = web3.eth.sign("0x135a7de83802408321b74c322f8558db1679ac20",
    "0x9dd2c369a187b4e6b9c402f030e50743e619301ea62aa4c0737d4ef7e10a3d49"); // second argument is web3.sha3("xyz")
console.log(result); // "0x30755ed65396facf86c53e6217c52b4daebe72aa4941d89635409de4c9c7f9466d4e9aaec7977f05e923889b33c0d0dd27d7226b6e6f56ce737465c5cfd04be400"

複製程式碼

備註:如果你使用以太坊的客戶端進行簽名時,它們會在你要簽名的資料前增加字首\x19Ethereum Signed Message:\n14,感謝讀者**@劉兵**同學的反饋。

eth_sign

The sign method calculates an Ethereum specific signature with: sign(keccak256("\x19Ethereum Signed Message:\n" + len(message) + message))).

By adding a prefix to the message makes the calculated signature recognisable as an Ethereum specific signature. This prevents misuse where a malicious DApp can sign arbitrary data (e.g. transaction) and use the signature to impersonate the victim.

web3.eth.call

web3.eth.call(callObject [, defaultBlock] [, callback])

在節點的VM中,直接執行訊息呼叫交易。但不會將資料合併區塊鏈中(這樣的呼叫不會修改狀態)。

引數:

  • Object - 返回一個交易物件,同web3.eth.sendTransaction。與sendTransaction的區別在於,from屬性是可選的。
  • Number|String -(可選)如果不設定此值使用web3.eth.defaultBlock設定的塊,否則使用指定的塊。
  • Function -(可選)回撥函式,用於支援非同步的方式執行7

返回值:

String - 函式呼叫返回的值。

示例:

var Web3 = require('web3');

if (typeof web3 !== 'undefined') {
  web3 = new Web3(web3.currentProvider);
} else {
  // set the provider you want from Web3.providers
  web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
}

var from = web3.eth.accounts[0];
//部署合約的釋出地址
/*合約內容如下
pragma solidity ^0.4.0;

contract Calc{
  function add(uint a, uint b) returns (uint){
    return a + b;
  }
}
*/
var to = "0xa4b813d788218df688d167102e5daff9b524a8bc";

//要傳送的資料
//格式說明見: http://me.tryblockchain.org/Solidity-call-callcode-delegatecall.html
var data = "0x771602f700000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002";

var result = web3.eth.call({
  from : from,
  to : to,
  data : data
});

//返回結果32字長的結果3
console.log(result);

複製程式碼

web3.eth.estimateGas

web3.eth.estimateGas(callObject [, callback])

在節點的VM節點中執行一個訊息呼叫,或交易。但是不會合入區塊鏈中。返回使用的gas量。

引數:

web3.eth.sendTransaction,所有的屬性都是可選的。

返回值:

Number - 模擬的call/transcation花費的gas

示例:

var result = web3.eth.estimateGas({
    to: "0xc4abd0339eb8d57087278718986382264244252f", 
    data: "0xc6888fa10000000000000000000000000000000000000000000000000000000000000003"
});
console.log(result); // "0x0000000000000000000000000000000000000000000000000000000000000015"

複製程式碼

web3.eth.filter

引數:

  • String|Object - 字串的可取值[latest,pending]。latest表示監聽最新的區塊變化,pending表示監聽正在pending的區塊。如果需要按條件物件過濾,如下:
    • fromBlock: Number|string - 起始區塊號(如果使用字串latest,意思是最新的,正在打包的區塊),預設值是latest
    • toBlock: Number|string - 終止區塊號(如果使用字串latest,意思是最新的,正在打包的區塊),預設值是latest
    • address: String - 單個或多個地址。獲取指定帳戶的日誌。
    • topics: String[] - 在日誌物件中必須出現的字串陣列。順序非常重要,如果你想忽略主題,使用null。如,[null,'0x00...'],你還可以為每個主題傳遞一個單獨的可選項陣列,如[null,['option1','option1']]。

返回值:

Object - 有下述方法的過濾物件。

  • filter.get(callback): 返回滿足過濾條件的日誌。
  • filter.watch(callback): 監聽滿足條件的狀態變化,滿足條件時呼叫回撥7
  • filter.stopWatching(): 停止監聽,清除節點中的過濾。你應該總是在監聽完成後,執行這個操作。

監聽回撥返回值:

  • String - 當使用latest引數時。返回最新的一個區塊雜湊值。
  • String - 當使用pending引數時。返回最新的pending中的交易雜湊值。
  • Object - 當使用手工過濾選項時,將返回下述的日誌物件。
    • logIndex: Number - 日誌在區塊中的序號。如果是pending的日誌,則為null
    • transactionIndex: Number - 產生日誌的交易在區塊中的序號。如果是pending的日誌,則為null
    • transactionHash: String,32位元組 - 產生日誌的交易雜湊值。
    • blockHash: String,32位元組 - 日誌所在塊的雜湊。如果是pending的日誌,則為null
    • blockNumber: Number - 日誌所在塊的塊號。如果是pending的日誌,則為null
    • address: String,32位元組 - 日誌產生的合約地址。
    • data: string - 包含日誌一個或多個32位元組的非索引的引數。
    • topics: String[] - 一到四個32位元組的索引的日誌引數陣列。(在Solidity中,第一個主題是整個事件的簽名(如,Deposit(address,bytes32,uint256)),但如果使用匿名的方式定義事件的情況除外)

事件監聽器的返回結果,見後合約物件的事件

示例:

var filter = web3.eth.filter('pending');

filter.watch(function (error, log) {
  console.log(log); //  {"address":"0x0000000000000000000000000000000000000000", "data":"0x0000000000000000000000000000000000000000000000000000000000000000", ...}
});

// get all past logs again.
var myResults = filter.get(function(error, logs){ ... });

...

// stops and uninstalls the filter
filter.stopWatching();

複製程式碼

web3.eth.contract

web3.eth.contract(abiArray)

建立一個Solidity的合約物件,用來在某個地址上初始化合約。

引數:

  • Array - 一到多個描述合約的函式,事件的ABI物件。

返回值:

Object - 一個合約物件。

示例:

var MyContract = web3.eth.contract(abiArray);

// instantiate by address
var contractInstance = MyContract.at([address]);

// deploy new contract
var contractInstance = MyContract.new([contructorParam1] [, contructorParam2], {data: '0x12345...', from: myAccount, gas: 1000000});

// Get the data to deploy the contract manually
var contractData = MyContract.new.getData([contructorParam1] [, contructorParam2], {data: '0x12345...'});
// contractData = '0x12345643213456000000000023434234'

複製程式碼

你可以或者使用一個在某個地址上已經存在的合約,或者使用編譯後的位元組碼部署一個全新的的合約。

// Instantiate from an existing address:
var myContractInstance = MyContract.at(myContractAddress);

// Or deploy a new contract:

// Deploy the contract asyncronous from Solidity file:
...
const fs = require("fs");
const solc = require('solc')

let source = fs.readFileSync('nameContract.sol', 'utf8');
let compiledContract = solc.compile(source, 1);
let abi = compiledContract.contracts['nameContract'].interface;
let bytecode = compiledContract.contracts['nameContract'].bytecode;
let gasEstimate = web3.eth.estimateGas({data: bytecode});
let MyContract = web3.eth.contract(JSON.parse(abi));

var myContractReturned = MyContract.new(param1, param2, {
   from:mySenderAddress,
   data:bytecode,
   gas:gasEstimate}, function(err, myContract){
    if(!err) {
       // NOTE: The callback will fire twice!
       // Once the contract has the transactionHash property set and once its deployed on an address.

       // e.g. check tx hash on the first call (transaction send)
       if(!myContract.address) {
           console.log(myContract.transactionHash) // The hash of the transaction, which deploys the contract

       // check address on the second call (contract deployed)
       } else {
           console.log(myContract.address) // the contract address
       }

       // Note that the returned "myContractReturned" === "myContract",
       // so the returned "myContractReturned" object will also get the address set.
    }
  });

// Deploy contract syncronous: The address will be added as soon as the contract is mined.
// Additionally you can watch the transaction by using the "transactionHash" property
var myContractInstance = MyContract.new(param1, param2, {data: myContractCode, gas: 300000, from: mySenderAddress});
myContractInstance.transactionHash // The hash of the transaction, which created the contract
myContractInstance.address // undefined at start, but will be auto-filled later

複製程式碼

示例:

// contract abi
var abi = [{
     name: 'myConstantMethod',
     type: 'function',
     constant: true,
     inputs: [{ name: 'a', type: 'string' }],
     outputs: [{name: 'd', type: 'string' }]
}, {
     name: 'myStateChangingMethod',
     type: 'function',
     constant: false,
     inputs: [{ name: 'a', type: 'string' }, { name: 'b', type: 'int' }],
     outputs: []
}, {
     name: 'myEvent',
     type: 'event',
     inputs: [{name: 'a', type: 'int', indexed: true},{name: 'b', type: 'bool', indexed: false}]
}];

// creation of contract object
var MyContract = web3.eth.contract(abi);

// initiate contract for an address
var myContractInstance = MyContract.at('0xc4abd0339eb8d57087278718986382264244252f');

// call constant function
var result = myContractInstance.myConstantMethod('myParam');
console.log(result) // '0x25434534534'

// send a transaction to a function
myContractInstance.myStateChangingMethod('someParam1', 23, {value: 200, gas: 2000});

// short hand style
web3.eth.contract(abi).at(address).myAwesomeMethod(...);

// create filter
var filter = myContractInstance.myEvent({a: 5}, function (error, result) {
  if (!error)
    console.log(result);
    /*
    {
        address: '0x8718986382264244252fc4abd0339eb8d5708727',
        topics: "0x12345678901234567890123456789012", "0x0000000000000000000000000000000000000000000000000000000000000005",
        data: "0x0000000000000000000000000000000000000000000000000000000000000001",
        ...
    }
    */
});

複製程式碼

合約物件的方法

// Automatically determines the use of call or sendTransaction based on the method type
myContractInstance.myMethod(param1 [, param2, ...] [, transactionObject] [, defaultBlock] [, callback]);

// Explicitly calling this method
myContractInstance.myMethod.call(param1 [, param2, ...] [, transactionObject] [, defaultBlock] [, callback]);

// Explicitly sending a transaction to this method
myContractInstance.myMethod.sendTransaction(param1 [, param2, ...] [, transactionObject] [, callback]);

// Get the call data, so you can call the contract through some other means
var myCallData = myContractInstance.myMethod.getData(param1 [, param2, ...]);
// myCallData = '0x45ff3ff6000000000004545345345345..'

複製程式碼

合約物件內封裝了使用合約的相關方法。可以通過傳入引數,和交易物件來使用方法。

引數:

  • String|Number - (可選)零或多個函式引數。如果傳入一個字串,需要使用十六進位制編碼,如,0xdedbeef
  • Object - (可選)最後一個引數(如果傳了callback,則是倒數第二個引數),可以是一個交易物件。檢視web3.eth.sendTransaction的第一個引數說明來了解更多。注意,這裡不需要填datato屬性。
  • Number|String -(可選)如果不設定此值使用web3.eth.defaultBlock設定的塊,否則使用指定的塊。
  • Function -(可選)回撥函式,用於支援非同步的方式執行7

返回值:

String - 如果發起的是一個call,對應的是返回結果。如果是transaction,則要麼是一個建立的合約地址,或者是一個transaction的雜湊值。檢視web3.eth.sendTransaction瞭解更多。

示例:

// creation of contract object
var MyContract = web3.eth.contract(abi);

// initiate contract for an address
var myContractInstance = MyContract.at('0x78e97bcc5b5dd9ed228fed7a4887c0d7287344a9');

var result = myContractInstance.myConstantMethod('myParam');
console.log(result) // '0x25434534534'

myContractInstance.myStateChangingMethod('someParam1', 23, {value: 200, gas: 2000}, function(err, result){ ... });

複製程式碼

合約物件的事件

你可以像web3.eth.filter這樣使用事件,他們有相同的方法,但需要傳遞不同的物件來建立事件過濾器。

引數:

  • Object - 你想返回的索引值(過濾哪些日誌)。如,{'valueA': 1, 'valueB': [myFirstAddress, mySecondAddress]}。預設情況下,所以有過濾項被設定為null。意味著預設匹配的是合約所有的日誌。
  • Object - 附加的過濾選項。參見web3.eth.filter的第一個引數。預設情況下,這個物件會設定address為當前合約地址,同時第一個主題為事件的簽名。
  • Function -(可選)傳入一個回撥函式,將立即開始監聽,這樣就不用主動呼叫myEvent.watch(function(){})7

回撥返回值:

Object - 事件物件,如下:

  • address: String,32位元組 - 日誌產生的合約地址。
  • args: Object - 事件的引數。
  • blockHash: String,32位元組 - 日誌所在塊的雜湊。如果是pending的日誌,則為null
  • blockNumber: Number - 日誌所在塊的塊號。如果是pending的日誌,則為null
  • logIndex: Number - 日誌在區塊中的序號。如果是pending的日誌,則為null
  • event: String - 事件名稱。
  • removed: bool - 標識產生事件的這個交易是否被移除(因為孤塊),或從未生效(被拒絕的交易)。
  • transactionIndex: Number - 產生日誌的交易在區塊中的序號。如果是pending的日誌,則為null
  • transactionHash: String,32位元組 - 產生日誌的交易雜湊值。

示例:

var MyContract = web3.eth.contract(abi);
var myContractInstance = MyContract.at('0x78e97bcc5b5dd9ed228fed7a4887c0d7287344a9');

// watch for an event with {some: 'args'}
var myEvent = myContractInstance.MyEvent({some: 'args'}, {fromBlock: 0, toBlock: 'latest'});
myEvent.watch(function(error, result){
   ...
});

// would get all past logs again.
var myResults = myEvent.get(function(error, logs){ ... });

...

// would stop and uninstall the filter
myEvent.stopWatching();

複製程式碼

合約 allEvents

var events = myContractInstance.allEvents([additionalFilterObject]);

// watch for changes
events.watch(function(error, event){
  if (!error)
    console.log(event);
});

// Or pass a callback to start watching immediately
var events = myContractInstance.allEvents([additionalFilterObject,] function(error, log){
  if (!error)
    console.log(log);
});

複製程式碼

呼叫合約建立的所有事件的回撥。

引數:

  • Object - 附加的過濾選項。參見web3.eth.filter的第一個引數。預設情況下,這個物件會設定address為當前合約地址,同時第一個主題為事件的簽名。
  • Function -(可選)傳入一個回撥函式,將立即開始監聽,這樣就不用主動呼叫myEvent.watch(function(){})7

回撥返回值:

Object - 詳見合約物件的事件瞭解更多。

示例:

var MyContract = web3.eth.contract(abi);
var myContractInstance = MyContract.at('0x78e97bcc5b5dd9ed228fed7a4887c0d7287344a9');

// watch for an event with {some: 'args'}
var events = myContractInstance.allEvents({fromBlock: 0, toBlock: 'latest'});
events.watch(function(error, result){
   ...
});

// would get all past logs again.
events.get(function(error, logs){ ... });

...

// would stop and uninstall the filter
myEvent.stopWatching();

複製程式碼

web3.eth.getCompilers

web3.eth.getCompilers([callback])

返回可用的編譯器。

引數值:

  • Function -(可選)回撥函式,用於支援非同步的方式執行7

返回值:

Array - 返回一個字串陣列,可用的編譯器。

web3.eth.compile.solidity

web3.eth.compile.solidity(sourceString [, callback])

編譯Solidity原始碼。

引數:

  • String - Solidity原始碼。
  • Function -(可選)回撥函式,用於支援非同步的方式執行7

返回值:

Object - 合約和編譯資訊。

示例:

var source = "" + 
    "contract test {\n" +
    "   function multiply(uint a) returns(uint d) {\n" +
    "       return a * 7;\n" +
    "   }\n" +
    "}\n";
var compiled = web3.eth.compile.solidity(source);
console.log(compiled); 
// {
  "test": {
    "code": "0x605280600c6000396000f3006000357c010000000000000000000000000000000000000000000000000000000090048063c6888fa114602e57005b60376004356041565b8060005260206000f35b6000600782029050604d565b91905056",
    "info": {
      "source": "contract test {\n\tfunction multiply(uint a) returns(uint d) {\n\t\treturn a * 7;\n\t}\n}\n",
      "language": "Solidity",
      "languageVersion": "0",
      "compilerVersion": "0.8.2",
      "abiDefinition": [
        {
          "constant": false,
          "inputs": [
            {
              "name": "a",
              "type": "uint256"
            }
          ],
          "name": "multiply",
          "outputs": [
            {
              "name": "d",
              "type": "uint256"
            }
          ],
          "type": "function"
        }
      ],
      "userDoc": {
        "methods": {}
      },
      "developerDoc": {
        "methods": {}
      }
    }
  }
}

複製程式碼

web3.eth.compile.lll

web3. eth.compile.lll(sourceString [, callback])

編譯LLL原始碼。

引數:

  • String - LLL原始碼。
  • Function -(可選)回撥函式,用於支援非同步的方式執行7

返回值:

String - 十六進位制格式編譯後的LLL編碼。

示例:

var source = "...";

var code = web3.eth.compile.lll(source);
console.log(code); // "0x603880600c6000396000f3006001600060e060020a600035048063c6888fa114601857005b6021600435602b565b8060005260206000f35b600081600702905091905056"

複製程式碼

web3.eth.compile.serpent

web3.eth.compile.serpent(sourceString [, callback])

編譯serpent原始碼。

引數:

  • String - serpent原始碼。
  • Function -(可選)回撥函式,用於支援非同步的方式執行7

返回值:

String - 十六進位制格式的編譯後的serpent編碼。

web3.eth.namereg

web3.eth.namereg

返回一個全球注意的物件。

使用方式:

檢視這裡的例子:github.com/ethereum/we…

web3.db

web3.db.putString

web3.db.putString(db, key, value)

這個方法應當在我們打算以一個本地資料庫的級別儲存一個字串時使用。

引數:

  • String - 儲存使用的資料庫。
  • String - 儲存的鍵。
  • String - 儲存的值。

返回值:

Boolean - true表示成功,否則返回false

示例:

web3.db.putString('testDB', 'key', 'myString') // true

複製程式碼

web3.db.getString

web3.db.getString(db, key)

從本地的leveldb資料庫中返回一個字串。

引數:

  • String - 儲存使用的資料庫。
  • String - 儲存的鍵。

返回值:

String - 儲存的值。

示例:

var value = web3.db.getString('testDB', 'key');
console.log(value); // "myString"

複製程式碼

web3.db.putHex

web3.db.putHex(db, key, value)

在本地的leveldb中儲存二進位制資料。

引數:

  • String - 儲存使用的資料庫。
  • String - 儲存的鍵。
  • String - 十六進位制格式的二進位制。

返回值:

Boolean - 成功返回true,失敗返回false

示例:

web3.db.putHex('testDB', 'key', '0x4f554b443'); // true

複製程式碼

web3.db.getHex

web3.db.getHex(db, key)

返回本地的leveldb中的二進位制資料。

引數:

  • String - 儲存使用的資料庫。
  • String - 儲存的鍵。

返回值:

String - 儲存的十六進位制值。

示例:

var value = web3.db.getHex('testDB', 'key');
console.log(value); // "0x4f554b443"
複製程式碼

5. 參考文件

1] Web3 JavaScript app API英文官網介面文件 2] Web3 JavaScript Ðapp API 3] WEB3.JS程式碼 4] WEB3的中文幫助文件地址 5] 以太坊DApp開發入門教程——區塊鏈投票系統 - 匯智網 6] Web3與智慧合約互動實戰 - 熊麗兵

相關文章