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

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

生活随笔

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

编程问答

java 以太坊 智能合约_web3j教程:java使用web3j开发以太坊智能合约交易

發(fā)布時(shí)間:2024/7/5 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java 以太坊 智能合约_web3j教程:java使用web3j开发以太坊智能合约交易 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

從廣義上講,有web3j支持三種類(lèi)型的以太坊交易:

1.以太幣從一方交易到另一方

2.創(chuàng)建一個(gè)智能合約

3.與智能合約交易

為了進(jìn)行這些交易,必須有以太幣(以太坊區(qū)塊鏈的代幣)存在于交易發(fā)生的以太坊賬戶(hù)中。這是為了支付gas成本,這是為支付參與交易的以太坊客戶(hù)端的交易執(zhí)行成本,支付了這個(gè)成本就能將結(jié)果提交到以太坊區(qū)塊鏈上。獲得以太幣的說(shuō)明下文會(huì)說(shuō)到。

此外,我們還可以查詢(xún)智能合約的狀態(tài)。

如何獲得以太幣Ether

要想獲得以太幣Ether你有兩種途徑可以選擇:

1.自己開(kāi)采挖礦

2.從別人那里獲取以太幣

在私有鏈中自己挖礦,或者公共測(cè)試鏈(testnet)是非常簡(jiǎn)單直接的。但是,在主要的公有鏈(mainnet)中,它需要很多很明顯的專(zhuān)用GPU時(shí)間,除非你已經(jīng)擁有多個(gè)專(zhuān)用GPU的礦機(jī),否則基本上不太可行。如果你希望使用私有鏈,則在這個(gè)官方文檔中有一些指導(dǎo)。

要購(gòu)買(mǎi)以太幣Ether,你需要通過(guò)交易所。由于不同的地區(qū)有不同的交易所,你還需要研究自己去哪兒合適。官方文檔中包含多個(gè)交易所,是一個(gè)很好的參考。

以太坊測(cè)試鏈(testnets)

針對(duì)Ethereum以太坊有許多專(zhuān)用測(cè)試網(wǎng)絡(luò)或者叫測(cè)試鏈,他們由各種客戶(hù)端支持。

1.Rinkeby:只支持geth客戶(hù)端。

2.Kovan:只支持Parity客戶(hù)端。

3.Ropsten:支持geth和Parity客戶(hù)端。

對(duì)于開(kāi)發(fā),建議你使用Rinkeby或KoVan測(cè)試鏈。這是因?yàn)樗麄兪褂玫墓ぷ髁孔C明POA共識(shí)機(jī)制,確保交易和塊能夠一致并及時(shí)的創(chuàng)建。Ropsten測(cè)試鏈,雖然最接近公有鏈(Mainnet),但是因?yàn)樗褂玫墓ぷ髁孔C明是POW共識(shí)機(jī)制,過(guò)去已受到攻擊,對(duì)以太坊開(kāi)發(fā)人員來(lái)說(shuō)往往有更多的問(wèn)題。

你可以通過(guò)Rinkeby測(cè)試鏈的Rinkeby Crypto Fauce請(qǐng)求以太坊幣,具體怎么做可以看這里https://www.rinkeby.io/。

有關(guān)如何請(qǐng)求Kovan測(cè)試鏈的細(xì)節(jié)可以在這里找到。

如果你需要在Ropsten上的得到一些以太幣,將你的錢(qián)包地址的消息發(fā)布到web3j gitter channel,然后會(huì)發(fā)送一些給你。

在testnet測(cè)試鏈或者私有鏈上挖掘

在ethereum以太坊測(cè)試鏈testnet中,挖掘難度低于公有鏈mainnet。這意味著你可以用普通的CPU,比如你的筆記本電腦來(lái)挖掘新的以太幣。你需要做的是運(yùn)行一個(gè)以太坊客戶(hù)端,例如geth或Parity,開(kāi)始做一些儲(chǔ)備。進(jìn)一步的資料可在他們的官方網(wǎng)站上獲得。

一旦你開(kāi)采了一些以太幣,你就可以開(kāi)始使用以太坊區(qū)塊鏈了。

然而,如上所述,使用Kovan或者Rinkeby測(cè)試網(wǎng)絡(luò)更簡(jiǎn)單些。

gas

當(dāng)在Ethereum以太坊發(fā)生交易時(shí),必須為執(zhí)行該交易的客戶(hù)端支付交易成本,將該交易的輸出提交到以太坊區(qū)塊鏈Ethereum blockchain。

此成本是通過(guò)gas來(lái)測(cè)量的,其中g(shù)as是用于在以太坊虛擬機(jī)中執(zhí)行交易指令的數(shù)量。請(qǐng)參閱官方文檔以獲取更多信息。

當(dāng)你使用以太坊客戶(hù)端時(shí),這意味著,有兩個(gè)參數(shù)用來(lái)指示你希望花費(fèi)多少以太來(lái)完成傳輸:

gas price :氣體價(jià)格,這是每單位gas中以太的消耗量。Web3j使用的默認(rèn)價(jià)格為22000000000 wei(22×10-8 Ether)。這是在交易管理中定義的。

gas limit:氣體最大量,這是你愿意在交易執(zhí)行上花費(fèi)的gas的最大總量。單個(gè)交易在一個(gè)以太坊區(qū)塊中有多大的上限,通常將該值限制為小于6700000。當(dāng)前的gas限制在這里查https://ethstats.net/。

這兩個(gè)參數(shù)共同決定了你愿意花費(fèi)在交易成本上的最大量的以太幣Ether。也就是說(shuō),你花費(fèi)的gas不會(huì)超過(guò)gas price * gas limit。gas價(jià)格也會(huì)影響交易發(fā)生的速度,這取決于其他交易是否能為礦工提供更有利的gas價(jià)格。

你可能需要調(diào)整這些參數(shù)以確保交易能及時(shí)進(jìn)行。

交易機(jī)制

當(dāng)你用一些以太幣Ether創(chuàng)建了一個(gè)有效的帳戶(hù)時(shí),你可以使用兩種機(jī)制來(lái)與以太坊進(jìn)行交易。

通過(guò)以太坊ethereum客戶(hù)端進(jìn)行認(rèn)證簽名交易

離線交易簽名認(rèn)證

這兩種機(jī)制都是Web3j所支持的。

通過(guò)以太坊ethereum客戶(hù)端進(jìn)行認(rèn)證簽名交易

為了通過(guò)以太坊客戶(hù)端進(jìn)行交易,首先需要確保你正在使用的客戶(hù)端知道你的錢(qián)包地址。最好是運(yùn)行自己的以太坊客戶(hù)端,比如geth/Parity,以便可以更方便的做到這一點(diǎn)。一旦你有一個(gè)客戶(hù)端運(yùn)行,你可以創(chuàng)建一個(gè)以太坊錢(qián)包,通過(guò):

geth Wiki包含了geth支持的良好運(yùn)行的不同機(jī)制,例如導(dǎo)入私有密鑰文件,并通過(guò)控制臺(tái)創(chuàng)建新的以太坊帳戶(hù)。

或者,你可以通過(guò)客戶(hù)端使用JSON-RPC管理命令,例如用personal_newAccount為geth/Parity創(chuàng)建新以太坊賬戶(hù)。

通過(guò)創(chuàng)建你的錢(qián)包文件,你可以通過(guò)web3j打開(kāi)帳戶(hù),首先創(chuàng)建支持geth/Parity管理命令的web3j實(shí)例:

Admin web3j = Admin.build(new HttpService());

然后,你可以解鎖帳戶(hù),并如果是成功的,就可以發(fā)送一個(gè)交易:

PersonalUnlockAccount personalUnlockAccount = web3j.personalUnlockAccount("0x000...", "a password").send();

if (personalUnlockAccount.accountUnlocked()) {

// send a transaction

}

Transaction transaction = Transaction.createContractTransaction(

,

,

BigInteger.valueOf(), // we use default gas limit

"0x..."

);

org.web3j.protocol.core.methods.response.EthSendTransaction

transactionResponse = parity.ethSendTransaction(ethSendTransaction)

.send();

String transactionHash = transactionResponse.getTransactionHash();

// poll for transaction response via org.web3j.protocol.Web3j.ethGetTransactionReceipt()

其中nonce值獲得方式,下文會(huì)提到。 有關(guān)此交易工作流的詳細(xì)信息,請(qǐng)參閱DeployContractIT和Scenario。

web3j支持的各種管理命令的進(jìn)一步細(xì)節(jié)在Management APIs中。

離線交易簽名認(rèn)證Offline transaction signing

如果你不想管理自己的以太坊客戶(hù)端,或者不想向以太坊客戶(hù)端提供諸如密碼之類(lèi)的錢(qián)包詳細(xì)信息,那么就通過(guò)離線交易認(rèn)證簽名。

離線交易簽名認(rèn)證允許你在web3j中使用你的以太坊錢(qián)包簽署交易,允許你完全控制你的私有憑據(jù)。然后,離線創(chuàng)建的交易可以被發(fā)送到網(wǎng)絡(luò)上的任何以太坊客戶(hù)端,只要它是一個(gè)有效的交易,它會(huì)將交易傳播到其他節(jié)點(diǎn)。

如果需要,還可以執(zhí)行進(jìn)程外交易簽名認(rèn)證。這可以通過(guò)重寫(xiě)ECKeyPair的sign方法來(lái)實(shí)現(xiàn)。

創(chuàng)建和使用錢(qián)包文件Ethereum wallet file

為了離線脫機(jī)交易,你需要有你的錢(qián)包文件或與私密錢(qián)包/賬戶(hù)相關(guān)的公共和私人密鑰。

web3j能夠?yàn)槟闵梢粋€(gè)新的安全的以太坊錢(qián)包文件Ethereum wallet file,或者與也可以通過(guò)私鑰來(lái)和現(xiàn)有的錢(qián)包文件一起工作。

創(chuàng)建新的錢(qián)包文件:

String fileName = WalletUtils.generateNewWalletFile(

"your password",

new File("/path/to/destination"));

加載憑據(jù)從錢(qián)包文件:

Credentials credentials = WalletUtils.loadCredentials(

"your password",

"/path/to/walletfile");

然后這些憑據(jù)會(huì)被用來(lái)簽署交易,請(qǐng)參閱Web3安全存儲(chǔ)定義錢(qián)包文件規(guī)范Web3 Secret Storage Definition

簽署以太坊交易

要使脫機(jī)簽名交易得到簽署,需要設(shè)定一個(gè)RawTransaction類(lèi)型。RawTransaction類(lèi)似于前面提到的Transaction類(lèi)型,但是它不需要通過(guò)具體的賬號(hào)地址來(lái)請(qǐng)求,因?yàn)榭梢詮暮灻型茢喑鰜?lái)。

為了創(chuàng)建和簽署原生交易,交易的順序如下:

1.確定交易發(fā)起者帳戶(hù)的下一個(gè)可用隨機(jī)數(shù)nonce

2.創(chuàng)建RawTransaction對(duì)象

3.使用遞歸長(zhǎng)度前綴編碼(RLP即Recursive Length Prefix)對(duì)RawTransaction對(duì)象進(jìn)行編碼

4.簽署RawTransaction對(duì)象

5.將RawTransaction對(duì)象發(fā)送到節(jié)點(diǎn)進(jìn)行處理

nonce是一個(gè)不斷增長(zhǎng)的數(shù)值,用來(lái)唯一地標(biāo)識(shí)交易。一個(gè)nonce只能使用一次,直到交易被挖掘完成,可以以相同的隨機(jī)數(shù)發(fā)送交易的多個(gè)版本,但是一旦其中一個(gè)被挖掘完成,其他后續(xù)提交的都將被拒絕。

一旦獲得下一個(gè)可用的nonce,該值就可以用來(lái)創(chuàng)建transaction對(duì)象:

RawTransaction rawTransaction = RawTransaction.createEtherTransaction(

nonce, , , , );

然后可以對(duì)交易進(jìn)行簽名和編碼:

byte[] signedMessage = TransactionEncoder.signMessage(rawTransaction, );

String hexValue = Numeric.toHexString(signedMessage);

其中憑據(jù)是根據(jù)創(chuàng)建和使用錢(qián)包文件加載的。

EthSendTransaction ethSendTransaction = web3j.ethSendRawTransaction(hexValue).sendAsync().get();

String transactionHash = ethSendTransaction.getTransactionHash();

// poll for transaction response via org.web3j.protocol.Web3j.ethGetTransactionReceipt()

交易隨機(jī)數(shù)nonce

nonce是一個(gè)不斷增長(zhǎng)的數(shù)值,用來(lái)唯一地標(biāo)識(shí)交易。一個(gè)nonce只能使用一次,直到交易被挖掘完成,可以以相同的隨機(jī)數(shù)發(fā)送交易的多個(gè)版本,但是一旦其中一個(gè)被挖掘完成,其他后續(xù)提交的都將被拒絕。

可以通過(guò)eth_getTransactionCount方法獲得下一個(gè)可用的nonce:

EthGetTransactionCount ethGetTransactionCount = web3j.ethGetTransactionCount(

address, DefaultBlockParameterName.LATEST).sendAsync().get();

BigInteger nonce = ethGetTransactionCount.getTransactionCount();

然后可以使用nonce創(chuàng)建你的交易對(duì)象:

RawTransaction rawTransaction = RawTransaction.createEtherTransaction(

nonce, , , , );

交易類(lèi)型

web3j中的不同類(lèi)型的交易都使用Transaction和RawTransaction對(duì)象。關(guān)鍵的區(qū)別是交易對(duì)象必須始終有一個(gè)地址,以便處理eth_sendTransaction請(qǐng)求的以太坊客戶(hù)端知道要使用哪個(gè)錢(qián)包來(lái)代表消息發(fā)送者并發(fā)送該交易。如上所述,對(duì)于離線簽名認(rèn)證簽署的原始交易而言,這不是必須的。

接下來(lái)的部分概述了不同交易類(lèi)型所需的關(guān)鍵交易屬性。下列屬性對(duì)所有人都是不變:

Gas price 天然氣氣體價(jià)格

Gas limit 天然氣氣體限制

Nonce 隨機(jī)數(shù)

from 發(fā)送地址

Transaction和RawTransaction對(duì)象在所有后續(xù)示例中都可互換使用。

以太幣從一方交易到另一方

在雙方之間發(fā)送以太幣Ether需要交易對(duì)象的最少量的信息:

to :目的地錢(qián)包地址

value:價(jià)值,希望發(fā)送到目的地的以太幣數(shù)量

BigInteger value = Convert.toWei("1.0", Convert.Unit.ETHER).toBigInteger();

RawTransaction rawTransaction = RawTransaction.createEtherTransaction(

, , , , value);

// send...

但是,建議你使用TransferClass來(lái)發(fā)送以太幣Ether,它負(fù)責(zé)對(duì)nonce管理和通過(guò)不斷的輪詢(xún)?yōu)槟闾峁╉憫?yīng):

Web3j web3 = Web3j.build(new HttpService()); // defaults to http://localhost:8545/

Credentials credentials = WalletUtils.loadCredentials("password", "/path/to/walletfile");

TransactionReceipt transactionReceipt = Transfer.sendFunds(

web3, credentials, "0x

|",

BigDecimal.valueOf(1.0), Convert.Unit.ETHER).send();

使用智能合約打包器smart contract wrappers

當(dāng)使用下面列出的智能合約打包器時(shí),將不得不手動(dòng)執(zhí)行從Solidity到本機(jī)Java類(lèi)型的所有轉(zhuǎn)換。使用Solidity smart contract wrappers是非常有效的,它負(fù)責(zé)所有的代碼生成和轉(zhuǎn)換。

創(chuàng)建一個(gè)智能合約

要部署新的智能合約,需要提供以下屬性:

value :在智能合約中希望存放的以太坊Ether量(如果沒(méi)有提供默認(rèn)為零)

data :十六進(jìn)制格式化、編譯的智能合約創(chuàng)建代碼

// using a raw transaction

RawTransaction rawTransaction = RawTransaction.createContractTransaction(

,

,

,

,

"0x ");

// send...

// get contract address

EthGetTransactionReceipt transactionReceipt =

web3j.ethGetTransactionReceipt(transactionHash).send();

if (transactionReceipt.getTransactionReceipt.isPresent()) {

String contractAddress = transactionReceipt.get().getContractAddress();

} else {

// try again

}

如果智能合約包含構(gòu)造函數(shù),則必須對(duì)關(guān)聯(lián)的構(gòu)造函數(shù)字段值進(jìn)行編碼,并將其附加到編譯的智能合約代碼中compiled smart contract code:

String encodedConstructor =

FunctionEncoder.encodeConstructor(Arrays.asList(new Type(value), ...));

// using a regular transaction

Transaction transaction = Transaction.createContractTransaction(

,

,

,

,

,

"0x " + encodedConstructor);

// send...

與智能合約交易

要與現(xiàn)有的智能合約進(jìn)行交易,需要提供以下屬性:

to:智能合同地址

value:在智能合約中你希望存放的以太幣Ether量(如果智能合約接受以太幣Ether的話(huà))

data: 已編碼的函數(shù)選擇器和自變量參數(shù)

web3j負(fù)責(zé)函數(shù)編碼,有關(guān)實(shí)現(xiàn)的進(jìn)一步細(xì)節(jié),請(qǐng)參閱應(yīng)用程序二進(jìn)制接口部分Application Binary Interface。

Function function = new Function<>(

"functionName", // function we're calling

Arrays.asList(new Type(value), ...), // Parameters to pass as Solidity Types

Arrays.asList(new TypeReference() {}, ...));

String encodedFunction = FunctionEncoder.encode(function)

Transaction transaction = Transaction.createFunctionCallTransaction(

, , , contractAddress, , encodedFunction);

org.web3j.protocol.core.methods.response.EthSendTransaction transactionResponse =

web3j.ethSendTransaction(transaction).sendAsync().get();

String transactionHash = transactionResponse.getTransactionHash();

// wait for response using EthGetTransactionReceipt...

無(wú)論消息簽名的返回類(lèi)型如何,都不可能從事務(wù)性函數(shù)調(diào)用返回值。但是,使用過(guò)濾器捕獲函數(shù)返回的值是可能的。詳情請(qǐng)參閱過(guò)濾器和事件部分。

查詢(xún)智能合約狀態(tài)

這種功能是由eth_call通過(guò)JSON-RPC調(diào)用來(lái)實(shí)現(xiàn)的。

eth_call允許你調(diào)用智能合約上的方法來(lái)查詢(xún)某個(gè)值。此函數(shù)沒(méi)有關(guān)聯(lián)交易成本,這是因?yàn)樗桓淖內(nèi)魏沃悄芎霞s方法的狀態(tài),它只返回它們的值:

Function function = new Function<>(

"functionName",

Arrays.asList(new Type(value)), // Solidity Types in smart contract functions

Arrays.asList(new TypeReference() {}, ...));

String encodedFunction = FunctionEncoder.encode(function)

org.web3j.protocol.core.methods.response.EthCall response = web3j.ethCall(

Transaction.createEthCallTransaction(, contractAddress, encodedFunction),

DefaultBlockParameterName.LATEST)

.sendAsync().get();

List someTypes = FunctionReturnDecoder.decode(

response.getValue(), function.getOutputParameters());

注意:如果一個(gè)無(wú)效的函數(shù)調(diào)用被執(zhí)行,或者得到一個(gè)空null返回結(jié)果時(shí),返回值將是一個(gè)Collections.emptyList實(shí)例。

web3j教程,主要是針對(duì)java和android程序員進(jìn)行區(qū)塊鏈以太坊開(kāi)發(fā)的web3j開(kāi)發(fā)詳解。

以太坊教程,主要介紹智能合約與dapp應(yīng)用開(kāi)發(fā),適合入門(mén)。

以太坊開(kāi)發(fā),主要是介紹使用node.js、mongodb、區(qū)塊鏈、ipfs實(shí)現(xiàn)去中心化電商DApp實(shí)戰(zhàn),適合進(jìn)階。

匯智網(wǎng)原創(chuàng)翻譯,轉(zhuǎn)載請(qǐng)標(biāo)明出處。原文訪問(wèn)其官方博客

總結(jié)

以上是生活随笔為你收集整理的java 以太坊 智能合约_web3j教程:java使用web3j开发以太坊智能合约交易的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

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