Web3j實現智能合約

1 獲取憑證java

Credentials是咱們錢包的憑證,在咱們交易和建立智能合約的時候都須要用到。linux

1.1 建立新憑證git

file=WalletUtils.generateFullNewWalletFile(pwd,dir);github

返回的file不是全路徑,而是該文件的路徑名,好比UTC—2017-10-30T12-10-45.516005546Z—5f38056f45091ee992298e53681b0a60c999ff95。web

前面的是建立時間,後面的是帳號標識。編程

1.2 使用舊憑證json

每一個帳號在建立的時候都會生成一個keystore,它是Json格式的。若是要使用舊憑證,首先須要找到咱們的keystore。我這裏的服務器搭建在linux服務端,因此這裏把keystore拷貝到咱們windows本地。windows

img

而後生成credentials服務器

img

 

2 智能合約maven

2.1 編寫智能合約

以太坊編寫智能合約有三種語言:

  • Serpent

Serpent是一種相似於Python的語言,可用於開發契約並編譯爲EVM字節碼。它旨在最大限度地簡化和清理,將低級語言的許多效率優點與易於使用的編程風格相結合,同時爲合同編程添加特定領域特定功能。蛇是使用LLL編譯的。

  • Solidity

這是一種相似於JavaScript的語言,它容許你開發合同並編譯爲EVM字節碼。它目前是以太坊的旗艦語言,也是最受歡迎的。

咱們這裏編寫一份Hello World

contract HelloWorld

{

address creator;

string greeting;

function HelloWorld(string _greeting) public

{

creator = msg.sender;

greeting = _greeting;

}

function greet() constant returns (string)

{

return greeting;

}

function setGreeting(string _newgreeting)

{

greeting = _newgreeting;

}

/

Standard kill() function to recover funds

/

function kill()

{

if (msg.sender == creator)

suicide(creator); // kills this contract and sends remaining funds back to creator

}

}

  • LLL

Lisp Like Language(LLL)是一種相似於Assembly的低級語言,它意味着很是簡單和簡約,基本上就是直接在EVM中進行編碼的一個小包裝。

還有一種已經被棄用了,這裏咱們選用官方標準的Solidity語言編寫。

2.2 編譯智能合約

這裏使用Solidity的在線編譯器https://ethereum.github.io/browser-solidity/

把咱們上面編寫好的智能合約代碼貼進去。

img

而後點擊Details

img

這裏的name就是智能合約的名稱,ABI文件會暴露合同的全部構造參數,咱們須要用ABI文件生成java類。WEB3是生成好的js文件,能夠配合web3.js直接調用。

2.3 Solidity類轉換成java類

若是想要避免使用智能合約的底層實現細節,web3j提供了Solidity 智能合約包裝,使您能夠經過生成的包裝對象直接與全部智能合約的方法進行交互。

這裏咱們把ABI文件複製一下,而後粘貼到本地做爲.json文件,名字最好和類名同樣,好比我這裏叫HelloWorld.json。這裏有一個大坑,就是編譯器生成的JSON文件格式不對,沒有合約名字,若是咱們執行轉換會報錯。

img

這裏咱們打開json文件手動編譯一下

img

web3j支持從Solidity ABI文件在Java中自動生成智能合約函數包裝器。

web3j 命令行工具附帶一個用於生成智能合同函數包裝器的命令行工具:

先去官方下載一個命令行工具

https://github.com/web3j/web3j/releases/tag/v3.2.0

img

下載.zip文件解壓到本地。

找到web3.bat文件執行 $ web3j truffle generate [—javaTypes|—solidityTypes] /path/to/.json -o /path/to/src/main/java -p com.your.organisation.name

上面這個是官方的格式不太通俗易懂,我給你們翻譯一下:

Web3j truffle generate json文件地址 -o 生成的文件目錄 -p 生成的文件包名。這裏要注意 -o 和-p也要帶上。

若是web3.bat文件點不開,就直接使用cmd命令執行,在執行的時候帶上web3j的全路徑就好了,執行完成以後控制條會顯示:

img

或者也能夠經過Java類進行調整,添加web3j的相關依賴,而後使用maven指定運行。

img

這裏把生成好的java類拷貝到咱們的代碼裏面。

2.4 發佈智能合約

合約生效時間

private static final String BINARY =null;

這個BINARY表明智能合約的生效時間,生成的類裏面默認是NULL. 若是不修改這個時間執行智能合約默認是失效的,因此這裏咱們修改一下爲官方指定的二進制代碼。

在編譯器裏面也能夠看到咱們生成的合約二進制文件。

img

就是這一行,咱們拷貝過來就行了。

部署智能合約

//部署智能合約

HelloWorld contract=deploy(admin, credentials,ManagedTransaction.GAS_PRICE, Contract.GAS_LIMIT,「Hello,World」).send();

部署合約須要消耗Gas.這裏說一下我對以太坊Gas的理解:

交易的過程通常須要支付必定量的手續費(固然也能夠選擇不支付)。礦工會優先打包交易手續費高的交易,若是沒有支付交易手續費,你的交易可能要等好久纔會被打包。建立一筆交易的時候不須要顯式的指明支付多少交易手續費,它是根據你的 UTXO額 – 交易額 – 找零 來計算的。舉個栗子,A有一個10btc的UTXO(未花費的交易輸出)的支配權,它給B帳戶轉1BTC,那麼在建立交易的時候,須要指明交易額1btc,和找零8.995,那麼(10-8.995-1 = 0.005)就是這筆交易的手續費,會獎勵給打包包含這筆交易的區塊的礦工,若是沒有設置找零那麼多餘的9btc都會被看成交易手續費獎勵給礦工,雖然你的交易會很快的被打包,可是這可能不是你想要的。

  • 這樣能夠鼓勵更加高效的合約代碼,減小沒必要要的計算,避免系統遭受攻擊,畢竟攻擊者要爲他們消耗的資源付出必定的代價,包括帶寬,CPU,和存儲。 gasPrice 是由交易的發起者來設置的,可是礦工能夠選擇先打包那些gas價格高的交易,gas價格低的可能要等好久或者不會被打包。
  • 例如一筆交易:{ from:web3.eth.accounts[0], data:tokenCompiled.token.code, gas: 1000000 }, gas參數設置這個交易最多能使用多少gas。交易裏面還能夠再加一個參數gasPrice,gasPrice能夠本身設置, geth會默認設置一個大多數礦工能夠接受的 gasPrice, 0.05e12 wei,能夠調eth.gasPrice來查看當前的gasPrice.
  • 礦工在啓動geth的時候能夠設置兩個參數—ask 和 —bid , —ask是設置一個最低的gas價格,低於這個價格的交易會被忽略,默認值是500000000000,—bid 設置gas價格競價,默認值是 500000000000。

合約地址

//獲取合約地址

String contractAddress = contract.getContractAddress();

合約發佈成功以後會在ETH客戶端生成一個合約地址,咱們在之後調用的時候都須要用到。

驗證合同是否有效

使用這種方法,您可能須要肯定已經加載的合同地址是您指望的智能合約。爲此,您可使用isValid智能合約方法,只有在合約地址已部署字節碼與智能合約包裝中的字節碼匹配時纔會返回true.

System.out.println(contract.isValid());

若是返回false,多是由於智能合約代碼生成的有問題,也有多是合同生效時間沒有設置。

加載智能合約

若是咱們想使用已經部署過的智能合約,這個時候咱們就須要加載智能合約了,

在加載智能合約的時候你須要擁有該智能合約的地址。

HelloWorld contract =HelloWorld.load(contractAddress,admin,credentials, GAS_PRICE, GAS_LIMIT);

調用智能合約

String value=contract.greet().send();

log.info(value);

調用咱們編譯好的get方法,會在控制檯打印Hello World。表明咱們此次合約部署調用成功。

銷燬智能合約

contract.kill();

銷燬後的智能合約沒法調用,可是能夠查詢到。

 

原文連接:http://wangxiaoming.com/blog/2018/01/22/HPB-41-ETH-3j-Smart/

相關文章
相關標籤/搜索