日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

以太坊开发实战:通过truffle-contract与智能合约交互

發(fā)布時(shí)間:2025/3/21 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 以太坊开发实战:通过truffle-contract与智能合约交互 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

以太坊開發(fā)實(shí)戰(zhàn):通過(guò)truffle-contract與智能合約交互

與以太坊的智能合約交互,除了使用web3.js,還可以使用另外一個(gè)Javascript庫(kù),就是truffle-contract。truffle-contract對(duì)以太坊的智能合約做了更好的抽象,相比于web3.js,使用truffle-contract操作智能合約更加方便。

truffle-contract具有以下特色:

  • 同步的交易:可以確保在交易生效之后再繼續(xù)執(zhí)行其他操作
  • 返回Promise:每個(gè)封裝的合約函數(shù)會(huì)返回Promise,可以對(duì)它進(jìn)行.then操作,避免了回調(diào)地獄(callback hell)問(wèn)題
  • 為交易提供了默認(rèn)參數(shù):例如from或gas
  • 為每個(gè)同步的交易返回logs、交易receipt和交易hash

下面介紹如何在應(yīng)用中使用truffle-contract與智能合約交互。

  • Ubuntu 16.04 64位
  • nodejs 6.10.0
  • npm 3.10.10

示例合約

還是以上一篇文章中的MetaCoin合約為例,確保啟動(dòng)了一個(gè)以太坊節(jié)點(diǎn),并且已將下面的MetaCoin合約部署到節(jié)點(diǎn)中。

pragma solidity ^0.4.2;

contract MetaCoin {

mapping (address => uint) balances;

event Transfer(address indexed _from, address indexed _to, uint256 _value);

function () {

balances[tx.origin] = 10000;

}

function sendCoin(address receiver, uint amount) returns(bool sufficient) {

if (balances[msg.sender] < amount) return false;

balances[msg.sender] -= amount;

balances[receiver] += amount;

Transfer(msg.sender, receiver, amount);

return true;

}

function getBalance(address addr) returns(uint) {

return balances[addr];

}

}

?

接下來(lái)就可以按照下面的步驟在項(xiàng)目中通過(guò)truffle-contract來(lái)使用這個(gè)合約。

安裝truffle-contract

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

$ mkdir truffle-contract-test && cd truffle-contract-test

$ npm init

?

接下來(lái)安裝truffle-contract:

$ npm install web3 --save

$ npm install truffle-contract --save

?

:安裝truffle-contract并不要求先安裝web3,這里安裝web3是因?yàn)楹竺鏁?huì)用到。

初始化合約對(duì)象

與web3.js類似,要使用truffle-contract,需要先初始化合約對(duì)象,然后連接到一個(gè)以太坊節(jié)點(diǎn)。在truffle-contract-test目錄下新建index.js文件,在其中輸入以下代碼:

var Web3 = require("web3");

var contract = require("truffle-contract");

// 合約ABI

var contract_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" }];

// 通過(guò)ABI初始化合約對(duì)象

var MetaCoin = contract({

abi: contract_abi

// 如果要部署合約,還要指定合約代碼:

// unlinked_binary: ...

});

// 連接到以太坊節(jié)點(diǎn)

var provider = new Web3.providers.HttpProvider("http://localhost:8545");

MetaCoin.setProvider(provider);

?

接下來(lái),可以使用MetaCoin的以下三個(gè)函數(shù):

  • at(contract_address):通過(guò)指定的合約地址獲取MetaCoin合約實(shí)例
  • deployed():通過(guò)默認(rèn)的合約地址獲取MetaCoin合約實(shí)例
  • new():部署新的合約,并且獲取新部署的合約實(shí)例

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

可以像下面這樣調(diào)用getBalance函數(shù):

// 改成你自己的賬戶地址

var account_one = "0x68b73956d704007514e9257813bdc58cdf3c969a";

// 合約地址,改成你自己的合約地址

var contract_address = "0xb2cdd356e58280906ce53e1665697b50f88aac56";

MetaCoin.at(contract_address).then(function(instance){

return instance.getBalance.call(account_one);

}).then(function(balance){

console.log(balance.toNumber());

}).catch(function(err){

console.log(err);

});

?

首先通過(guò)MetaCoin.at()獲取合約實(shí)例,在.then鏈?zhǔn)秸{(diào)用中,回調(diào)函數(shù)會(huì)在參數(shù)中獲取到合約實(shí)例instance,接下來(lái)就可以在回調(diào)函數(shù)中使用合約實(shí)例來(lái)調(diào)用getBalance函數(shù),再繼續(xù)通過(guò).then鏈?zhǔn)秸{(diào)用,通過(guò)回調(diào)函數(shù)獲得getBalance的返回值balance。

再來(lái)看看調(diào)用sendCoin函數(shù)的情況:

// 改成你自己的賬戶地址

var account_one = "0x68b73956d704007514e9257813bdc58cdf3c969a";

var account_two = "0x9c3c1a2f5ef913fac44f0348a78f68d835f3f26e";

// 合約地址,改成你自己的合約地址

var contract_address = "0xb2cdd356e58280906ce53e1665697b50f88aac56";

MetaCoin.at(contract_address).then(function(instance){

// 調(diào)用sendCoin會(huì)向區(qū)塊鏈發(fā)送一筆交易

return instance.sendCoin(account_two, 100, {from:account_one});

}).then(function(result){

// 這個(gè)回調(diào)函數(shù)在交易生效之后才會(huì)被執(zhí)行

// result對(duì)象包含以下三個(gè)字段:

// result.tx => 交易hash,是一個(gè)string

// result.receipt => 交易執(zhí)行結(jié)果,是一個(gè)對(duì)象

// result.logs => 交易產(chǎn)生的事件集合,是一個(gè)對(duì)象數(shù)組

console.log(result);

}).catch(function(err){

console.log(err);

});

?

這里,調(diào)用sendCoin會(huì)向區(qū)塊鏈發(fā)送一筆交易,在交易生效之后,才會(huì)執(zhí)行回調(diào)函數(shù),回調(diào)函數(shù)的參數(shù)中包含了交易hash、交易執(zhí)行結(jié)果以及交易產(chǎn)生的事件。

捕獲事件

可以通過(guò)result.logs獲取交易觸發(fā)的事件:

// 改成你自己的賬戶地址

var account_one = "0x68b73956d704007514e9257813bdc58cdf3c969a";

var account_two = "0x9c3c1a2f5ef913fac44f0348a78f68d835f3f26e";

// 合約地址,改成你自己的合約地址

var contract_address = "0xb2cdd356e58280906ce53e1665697b50f88aac56";

MetaCoin.at(contract_address).then(function(instance){

// 調(diào)用sendCoin會(huì)向區(qū)塊鏈發(fā)送一筆交易

return instance.sendCoin(account_two, 100, {from:account_one});

}).then(function(result){

// 這個(gè)回調(diào)函數(shù)在交易生效之后才會(huì)被執(zhí)行

// result.logs是一個(gè)數(shù)組,數(shù)組的每個(gè)元素是一個(gè)事件對(duì)象

// 通過(guò)查詢r(jià)esult.logs可以獲得感興趣的事件

for (var i = 0; i < result.logs.length; i++) {

var log = result.logs[i];

if (log.event == "Transfer") {

console.log("from:", log.args._from);

console.log("to:", log.args._to);

console.log("amount:", log.args._value.toNumber());

break;

}

}

}).catch(function(err){

console.log(err);

});

// 輸出:

from: 0x68b73956d704007514e9257813bdc58cdf3c969a

to: 0x9c3c1a2f5ef913fac44f0348a78f68d835f3f26e

amount: 100

?

sendCoin執(zhí)行完后會(huì)觸發(fā)一個(gè)Transfer事件,在回調(diào)函數(shù)中,通過(guò)查詢r(jià)esult.logs可以獲取到這個(gè)事件,進(jìn)而可以得到事件的參數(shù)值。

一個(gè)完整的例子

下面是一個(gè)完整的例子:

var Web3 = require("web3");

var contract = require("truffle-contract");

// 合約ABI

var contract_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" }];

// 通過(guò)ABI初始化合約對(duì)象

var MetaCoin = contract({

abi: contract_abi

// 如果要部署合約,還要指定合約代碼:

// unlinked_binary: ...

});

// 連接到以太坊節(jié)點(diǎn)

var provider = new Web3.providers.HttpProvider("http://localhost:8545");

MetaCoin.setProvider(provider);

// 改成你自己的賬戶地址

var account_one = "0x68b73956d704007514e9257813bdc58cdf3c969a";

var account_two = "0x9c3c1a2f5ef913fac44f0348a78f68d835f3f26e";

// 合約地址,改成你自己的合約地址

var contract_address = "0xb2cdd356e58280906ce53e1665697b50f88aac56";

var coin;

MetaCoin.at(contract_address).then(function(instance){

coin = instance;

// 首先查看賬戶二的余額

return coin.getBalance.call(account_two);

}).then(function(balance_of_account_two){

console.log("Balance of account two is", balance_of_account_two.toNumber());

// 從賬戶一向賬戶二轉(zhuǎn)100個(gè)幣

return coin.sendCoin(account_two, 100, {from:account_one});

}).then(function(result){

console.log("Sent 100 coin from account one to account two.");

// 再次查看賬戶二的余額

return coin.getBalance.call(account_two);

}).then(function(balance_of_account_two){

console.log("Balance of account two is", balance_of_account_two.toNumber());

}).catch(function(err){

console.log("Error:", err.message);

});

?

// 輸出

Balance of account two is 3400

Sent 100 coin from account one to account two.

Balance of account two is 3500

總結(jié)

以上是生活随笔為你收集整理的以太坊开发实战:通过truffle-contract与智能合约交互的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。