<thead id="kdfuf"><font id="kdfuf"></font></thead>
<samp id="kdfuf"></samp>
    <nav id="kdfuf"><strong id="kdfuf"></strong></nav>
      中文字幕无码一区二区三区在线,久久精品人人做人人爽,国产一级内射无挡观看,十八禁在线黄色网站,日韩欧美国产另类久久久精品 ,少妇人妻偷人精品一区二区,久久午夜视频,亚洲春色AⅤ无码专区

      智能合約 web3.js ABI Address三者的關(guān)系

      2021-9-24    前端達(dá)人

      web3.js是以太坊提供的一個(gè)Javascript庫,它封裝了以太坊的JSON RPC API,提供了一系列與區(qū)塊鏈交互的Javascript對象和函數(shù),包括查看網(wǎng)絡(luò)狀態(tài),查看本地賬戶、查看交易和區(qū)塊、發(fā)送交易、編譯/部署智能合約、調(diào)用智能合約等,其中最重要的就是與智能合約交互的API。

      下面就介紹如何使用web3.js提供的接口調(diào)用智能合約。

      系統(tǒng)和軟件

      
      
      1. Ubuntu 16.04 64
      2. nodejs 6.10.0
      3. npm 3.10.10

      示例合約

      本文以下面的MetaCoin合約為例,說明在應(yīng)用中使用web3.js操作智能合約的方法。

      
      
      1. // 本文中用到的MetaCoin合約
      2. pragma solidity ^0.4.2;
      3. contract MetaCoin {
      4. mapping (address => uint) balances;
      5. event Transfer(address indexed _from, address indexed _to, uint256 _value);
      6. function MetaCoin() {
      7. balances[tx.origin] = 10000;
      8. }
      9. function sendCoin(address receiver, uint amount) returns(bool sufficient) {
      10. if (balances[msg.sender] < amount) return false;
      11. balances[msg.sender] -= amount;
      12. balances[receiver] += amount;
      13. Transfer(msg.sender, receiver, amount);
      14. return true;
      15. }
      16. function getBalance(address addr) returns(uint) {
      17. return balances[addr];
      18. }
      19. }

      這個(gè)合約有三個(gè)函數(shù):

      MetaCoin:構(gòu)造函數(shù),在合約被部署到區(qū)塊鏈時(shí)執(zhí)行 
      getBalance:返回某賬戶的余額,它只讀數(shù)據(jù),不會修改數(shù)據(jù) 
      sendCoin:向另一個(gè)賬戶發(fā)送指定數(shù)量的MetaCoin,它會改變狀態(tài)變量balances 
      啟動(dòng)一個(gè)以太坊節(jié)點(diǎn),將上面的合約部署到區(qū)塊鏈中,并記錄下合約的地址,可以通過truffle部署,具體參考這篇文章。 接下來就可以按照下面的步驟在項(xiàng)目中通過web3.js來使用這個(gè)合約。

      添加web3到項(xiàng)目中

      首先新建一個(gè)Nodejs項(xiàng)目并初始化:

      
      
      1. $ mkdir web3test && cd web3test
      2. $ npm init

      會提示輸入項(xiàng)目信息,全部默認(rèn)即可。 
      接下來下載web3.js到項(xiàng)目中:

      $ npm install web3 --save 
      • 1
      • 2

      以上命令會將web3.js下載到web3test/node_modules目錄下,其中–save參數(shù)會web3.js添加到package.json配置文件中。

      創(chuàng)建web3對象

      要使用web3.js與區(qū)塊鏈交互,需要先創(chuàng)建web3對象,然后連接到以太坊節(jié)點(diǎn)。 在web3test目錄下新建index.js文件,在其中輸入以下代碼:

      
      
      1. var Web3 = require("web3");
      2. // 創(chuàng)建web3對象
      3. var web3 = new Web3();
      4. // 連接到以太坊節(jié)點(diǎn)
      5. web3.setProvider(new Web3.providers.HttpProvider("http://localhost:8545"));

      獲取已部署的合約實(shí)例

      要使用智能合約,必須先從區(qū)塊鏈中獲取到合約實(shí)例,獲取合約實(shí)例需要合約的ABI和合約的地址:

      
      
      1. // 合約ABI
      2. var abi = [{"constant":false,"inputs":[{"name":"receiver","type":"address"},{"name":"amount","type":"uint256"}],"name":"sendCoin","outputs":[{"name":"sufficient","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"addr","type":"address"}],"name":"getBalance","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"inputs":[],"payable":false,"type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_from","type":"address"},{"indexed":true,"name":"_to","type":"address"},{"indexed":false,"name":"_value","type":"uint256"}],"name":"Transfer","type":"event"}];
      3. // 合約地址
      4. var address = "0xb2cdd356e58280906ce53e1665697b50f88aac56";
      5. // 通過ABI和地址獲取已部署的合約對象
      6. var metacoin = web3.eth.contract(abi).at(address);

      metacoin就是獲取到的合約對象實(shí)例,此時(shí)metacoin對象中就包含了與合約函數(shù)同名的Javascript函數(shù),之后就可以通過metacoin對象來調(diào)用合約中的函數(shù)了。

      調(diào)用合約函數(shù)

      MetaCoin合約中有兩個(gè)函數(shù):getBalance和sendCoin,可以通過metacoin對象直接調(diào)用這兩個(gè)函數(shù)。

      首先來看getBalance,由于getBalance函數(shù)只是從區(qū)塊鏈中讀數(shù)據(jù),而不修改數(shù)據(jù),因此我們通過在getBalance后面加上.call()的方式調(diào)用:

      
      
      1. var account_one = web3.eth.accounts[0];
      2. var account_one_balance = metacoin.getBalance.call(account_one);
      3. console.log("account one balance: ", account_one_balance.toNumber());

      這里:

      在getBalance后加上.call()來顯式指明用call的方式調(diào)用 
      通過call的方式調(diào)用可以得到getBalance函數(shù)的返回值 
      通過call的方式調(diào)用的函數(shù)只在節(jié)點(diǎn)本地虛擬機(jī)中執(zhí)行,不會產(chǎn)生交易,不會花費(fèi)費(fèi)用,不會修改數(shù)據(jù) 
      下面來看sendCoin函數(shù),由于sendCoin要修改合約內(nèi)部的數(shù)據(jù),所以要使sendCoin生效,必須要向區(qū)塊鏈發(fā)送交易,可以在sendCoin后面加上.sendTransaction()來指明這是一筆交易:

      
      
      1. var account_one = web3.eth.accounts[0];
      2. var account_two = web3.eth.accounts[1];
      3. // 提交交易到區(qū)塊鏈,會立即返回交易hash,但是交易要等到被礦工收錄到區(qū)塊中后才生效
      4. var txhash = metacoin.sendCoin.sendTransaction(account_two, 100, {from:account_one});
      5. console.log(txhash);

      這里:

      在sendCoin函數(shù)后加上.sendTransaction()指明要向區(qū)塊鏈發(fā)送交易 
      合約代碼中sendCoin函數(shù)只有兩個(gè)參數(shù),而在web3中通過.sendTransaction()調(diào)用合約函數(shù)的時(shí)候需要增加最后一個(gè)參數(shù),它是一個(gè)javascript對象,里面可以指定from/value/gas等屬性,上面的例子用from來指定交易的發(fā)送者 
      上面的調(diào)用語句執(zhí)行后,會向區(qū)塊鏈提交一筆交易,這筆交易的發(fā)送者是account_one,接收者是metacoin的地址,交易的作用是以account_two和100作為參數(shù)執(zhí)行合約的sendCoin函數(shù) 
      函數(shù)會立即返回交易的hash,表明交易已經(jīng)提交到區(qū)塊鏈,但是并不知道交易何時(shí)處理完成,交易要等到被曠工收錄到區(qū)塊中后才會生效 
      監(jiān)聽合約事件

      當(dāng)通過.sendTransaction()調(diào)用合約的時(shí)候,交易會被提交到區(qū)塊鏈進(jìn)行處理,這個(gè)處理需要一定的時(shí)間,如果需要等交易完成之后再執(zhí)行其他操作,就必須要知道交易何時(shí)完成,那么如何知道交易何時(shí)完成呢?可以通過監(jiān)聽合約事件來實(shí)現(xiàn)。

      在合約中可以定義事件,事件可以帶有參數(shù),在合約函數(shù)內(nèi)部完成某些操作時(shí),可以觸發(fā)事件,向外界傳達(dá)一些信息。例如,在MetaCoin合約中定義了一個(gè)事件叫做Transfer,表示一個(gè)轉(zhuǎn)賬的事件,它帶有三個(gè)參數(shù):交易的發(fā)送者、接受者、轉(zhuǎn)賬數(shù)量。在sendCoin函數(shù)中,轉(zhuǎn)賬成功后就會觸發(fā)Transfer事件,將對應(yīng)的參數(shù)傳給該事件,這樣外部監(jiān)聽到事件后,可以取出事件的參數(shù)來獲得交易發(fā)送者、接收者、數(shù)量。同時(shí)事件中還帶有其他信息,比如交易hash等。

      在web3中使用事件,要首先獲取事件對象,然后監(jiān)聽事件,如果事件發(fā)生,就會在回調(diào)函數(shù)中獲取到事件信息:

      
      
      1. // 獲取事件對象
      2. var myEvent = metacoin.Transfer();
      3. // 監(jiān)聽事件,監(jiān)聽到事件后會執(zhí)行回調(diào)函數(shù)
      4. myEvent.watch(function(err, result) {
      5. if (!err) {
      6. console.log(result);
      7. } else {
      8. console.log(err);
      9. }
      10. myEvent.stopWatching();
      11. });
      12. // 輸出:
      13. { address: '0xb2cdd356e58280906ce53e1665697b50f88aac56',
      14. blockNumber: 651,
      15. transactionIndex: 0,
      16. transactionHash: '0xcc71bc2824cc84d1ee831c46189e3a80cf0af05697ba0370693aa97390c8067b',
      17. blockHash: '0x1d53f04206f3926d0f311b1230a9dd0b0c5aadac35b169a6a609e384ab130c6f',
      18. logIndex: 0,
      19. removed: false,
      20. event: 'Transfer',
      21. args:
      22. { _from: '0x68b73956d704007514e9257813bdc58cdf3c969a',
      23. _to: '0x9c3c1a2f5ef913fac44f0348a78f68d835f3f26e',
      24. _value: { [String: '100'] s: 1, e: 2, c: [Object] } } }


      從輸出可以看出,獲取到的事件信息包括事件的參數(shù)、事件名、區(qū)塊號、交易hash等。

      通過檢測事件中的transactionHash與調(diào)用合約函數(shù)返回的交易hash是否一致,可以判定某一筆交易是否已完成:

      
      
      1. var account_one = web3.eth.accounts[0];
      2. var account_two = web3.eth.accounts[1];
      3. var account_one_balance = metacoin.getBalance.call(account_one);
      4. console.log("account one balance:", account_one_balance.toNumber());
      5. var txhash = metacoin.sendCoin.sendTransaction(account_two, 100, { from: account_one });
      6. var myEvent = metacoin.Transfer();
      7. myEvent.watch(function (err, result) {
      8. if (!err) {
      9. if (result.transactionHash == txhash) {
      10. var account_one_balance = metacoin.getBalance.call(account_one);
      11. console.log("account one balance after sendCoin:", account_one_balance.toNumber());
      12. }
      13. } else {
      14. console.log(err);
      15. }
      16. myEvent.stopWatching();
      17. });
      18. // 輸出:
      19. account one balance: 7000
      20. account one balance after sendCoin: 6900


      watch中的回調(diào)函數(shù)如果被執(zhí)行,說明事件已被觸發(fā),也就是說某筆交易已經(jīng)處理完,檢查交易hash是否一致,可以判定產(chǎn)生這個(gè)事件的交易是否是自己發(fā)送的交易,如果是,就可以進(jìn)行其他操作,比如查詢最新的余額


      藍(lán)藍(lán)設(shè)計(jì)建立了UI設(shè)計(jì)分享群,每天會分享國內(nèi)外的一些優(yōu)秀設(shè)計(jì),如果有興趣的話,可以進(jìn)入一起成長學(xué)習(xí),請掃碼藍(lán)小助,報(bào)下信息,藍(lán)小助會請您入群。歡迎您加入噢~~希望得到建議咨詢、商務(wù)合作,也請與我們聯(lián)系。

      分享此文一切功德,皆悉回向給文章原作者及眾讀者.

      轉(zhuǎn)自:csdn
      免責(zé)聲明:藍(lán)藍(lán)設(shè)計(jì)尊重原作者,文章的版權(quán)歸原作者。如涉及版權(quán)問題,請及時(shí)與我們?nèi)〉寐?lián)系,我們立即更正或刪除。

      藍(lán)藍(lán)設(shè)計(jì)www.tuitetiyu.cn )是一家專注而深入的界面設(shè)計(jì)公司,為期望卓越的國內(nèi)外企業(yè)提供卓越的UI界面設(shè)計(jì)、BS界面設(shè)計(jì) 、 cs界面設(shè)計(jì) 、 ipad界面設(shè)計(jì) 、 包裝設(shè)計(jì) 、 圖標(biāo)定制 、 用戶體驗(yàn) 、交互設(shè)計(jì)、 網(wǎng)站建設(shè) 平面設(shè)計(jì)服務(wù)


      日歷

      鏈接

      個(gè)人資料

      存檔

      主站蜘蛛池模板: 最近的中文字幕在线看视频| 免费a级毛视频| 日韩av无码一区二区三区 | haodiaoniu精品国产| 国产美女销魂在线观看不卡| 昆明市| 亚洲精品一区中文字幕乱码| 人与牲口性恔配视频免费l| 日韩女同一区二区三区久久| 久久精品亚洲AV无码四区| 少妇高清精品毛片在线视频| 日本一二三区视频在线| 影院精品久久久无码| 最近最好的中文字幕免费| 国产精品成人免费久久黄AV片| 国产欧美色一区| 女人被躁到高潮嗷嗷叫免费| 亚洲国产精品久久一线不卡| 亚洲熟妇AV乱码在线观看| 成年无码按摩AV片在线| 日韩在线视频播放| kkkk国产在线播放| 国产高清在线精品一区| 欧美激情综合一区二区三区| 护士人妻HD中文字幕| 九九热在线免费| 国产精品欧美亚洲制服| 狠狠色综合TV久久久久久| 日本带啪的纯肉免费动漫| 好男人视频在线观看| 国产精品无码久久久久久久久久久| 精品无码国产自产拍在线观看| 无码射肉在线播放视频| 91精品乱码一区二区三区| 天堂网av一区二区三区| 少妇厨房愉情理伦片bd在线观看| av天堂资源在线| 日韩精品欧美大片资源| 国产精品久久久久久亚洲| 精品乱码一区内射人妻无码| 无码国产福利AV私拍|