今天會用到的工具是
web3 呼叫 geth api
版本 3.5
solc 編寫智能合約
版本 3.5
solc 編寫智能合約
編寫智能合約
solc 可以直接把 合約檔案,大家可以在之前編寫環境 去那邊做 語法檢測 檢測完,再存入sol 檔
可以發現在上一層目錄 產生了兩個檔, 一個就是 bin二進制數據文件
另一個好像是 abi二進位制介面 可以去查一下。
好了之後 我們複製檔案到 我們的web3 目錄下 ,我們這邊直接執行
可以發現在上一層目錄 產生了兩個檔, 一個就是 bin二進制數據文件
另一個好像是 abi二進位制介面 可以去查一下。
好了之後 我們複製檔案到 我們的web3 目錄下 ,我們這邊直接執行
web3j solidity generate Token.bin Token.abi -p contract -o /
編譯好後 我們回到最上層目錄
這邊就可以看到我們用 web3 轉換出來的 合約檔案了,準備來引用一下。
spring boot
配置檔
這邊配置 3.5
<dependency>
<groupId>org.web3j</groupId>
<artifactId>core</artifactId>
<version>3.5.0</version>
</dependency>
主程式
import java.io.IOException;
import java.math.BigInteger;
import org.web3j.crypto.CipherException;
import org.web3j.crypto.Credentials;
import org.web3j.crypto.WalletUtils;
import org.web3j.protocol.Web3j;
import org.web3j.protocol.core.DefaultBlockParameterName;
import org.web3j.protocol.core.methods.request.EthFilter;
import org.web3j.protocol.core.methods.response.Web3ClientVersion;
import org.web3j.protocol.http.HttpService;
import org.web3j.tx.gas.DefaultGasProvider;
public class web3test {
//private final static String PRIVATE_KEY = "eb239949bb46a187b4ff1645a13a9c0c146f7e0890d18426a639ae3add6b690a";
private static Credentials getCredentialsFromPrivateKeyAddress() throws IOException, CipherException {
Credentials credentials = WalletUtils.loadCredentials( "654321","F:\\geth\\data\\keystore\\UTC--2020-01-03T05-58-33.219268500Z--21d10c5e114a959e6e92c6f5f0ffcbe7df7785f1");
return credentials;
}
//這邊兩個分別是 我們進到 我們geth 裡面的 data keystore
//裡面就是存放著我們一開始創建好的帳戶 我們要指定其中一 個然後設定目標帳戶
// private static Credentials getCredentialsFromPrivateKeyAddress() throws Exception {
// Credentials credentials = WalletUtils.loadCredentials("eb239949bb46a187b4ff1645a13a9c0c146f7e0890d18426a639ae3add6b690a", "0xDB24eE35b51cA44C60152628e5Cf32B5AE262364");
// return credentials;
// }
private static Credentials getCredentialsFromPrivateKey(){
return Credentials.create(PRIVATE_KEY);
}
private final static BigInteger GAS_LIMIT = BigInteger.valueOf(210000000L);
private final static BigInteger GAS_PRICE = BigInteger.valueOf(10000L);
private static String deployContract(Web3j web3j, Credentials credentials) throws Exception{
return Token.deploy(web3j, credentials, GAS_PRICE, GAS_LIMIT).send().getContractAddress();
}
private static Token loadContract(String address, Web3j web3j, Credentials credentials){
return Token.load(address, web3j, credentials, GAS_PRICE, GAS_LIMIT);
}
private static void activateFilter(Web3j web3j, String contractAddress,Token exampleContract){
EthFilter filter = new EthFilter(DefaultBlockParameterName.EARLIEST, DefaultBlockParameterName.LATEST, contractAddress);
exampleContract.setBalanceEventEventObservable(filter).subscribe(log-> System.out.println(log.toString()));
exampleContract.setBalanceEventEventObservable(filter).subscribe(log-> System.out.println(log.balance));
web3j.ethLogObservable(filter).subscribe(log -> System.out.println(log.toString()));
}
public static void main(String[] args) throws Exception {
Web3j web3 = Web3j.build(new HttpService()); // defaults to http://localhost:8545/
Web3ClientVersion web3ClientVersion = web3.web3ClientVersion().sendAsync().get();
String clientVersion = web3ClientVersion.getWeb3ClientVersion();
Credentials credentials = getCredentialsFromPrivateKeyAddress();
String deployedContract = deployContract(web3, credentials).toString();
//Thread.sleep(30000);
Token exampleContract = loadContract(deployedContract, web3, credentials);
System.out.println("Deployed contract address; "+ deployedContract);
System.out.println("----------------------------------------");
activateFilter(web3, deployedContract ,exampleContract);
Boolean result = exampleContract.isValid();
System.out.println("ok"+result);
exampleContract.setBalance("Alice", BigInteger.valueOf(4)).send();
System.out.println("ok");
Object ans = exampleContract.returnBalance("Alice").send();
System.out.println("ok");
System.out.println("user-defined message: " + ans.toString());
ans = exampleContract.returnBalance("Bob").send();
System.out.println("user-defined message: " + ans.toString());
}
}
智能合約
package com.example.demo;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.web3j.abi.EventEncoder;
import org.web3j.abi.TypeReference;
import org.web3j.abi.datatypes.Event;
import org.web3j.abi.datatypes.Function;
import org.web3j.abi.datatypes.Type;
import org.web3j.abi.datatypes.Utf8String;
import org.web3j.abi.datatypes.generated.Uint256;
import org.web3j.crypto.Credentials;
import org.web3j.protocol.Web3j;
import org.web3j.protocol.core.DefaultBlockParameter;
import org.web3j.protocol.core.RemoteCall;
import org.web3j.protocol.core.methods.request.EthFilter;
import org.web3j.protocol.core.methods.response.Log;
import org.web3j.protocol.core.methods.response.TransactionReceipt;
import org.web3j.tx.Contract;
import org.web3j.tx.TransactionManager;
import rx.Observable;
import rx.functions.Func1;
/**
* <p>Auto generated code.
* <p><strong>Do not modify!</strong>
* <p>Please use the <a href="https://docs.web3j.io/command_line.html">web3j command line tools</a>,
* or the org.web3j.codegen.SolidityFunctionWrapperGenerator in the
* <a href="https://github.com/web3j/web3j/tree/master/codegen">codegen module</a> to update.
*
* <p>Generated with web3j version 3.5.0.
*/
public class Token extends Contract {
private static final String BINARY = "608060405234801561001057600080fd5b506102f9806100206000396000f30060806040526004361061004c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063361ab84f1461005157806338639f7b146100ce575b600080fd5b34801561005d57600080fd5b506100b8600480360381019080803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509192919290505050610141565b6040518082815260200191505060405180910390f35b3480156100da57600080fd5b5061013f600480360381019080803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509192919290803590602001909291905050506101b5565b005b600080826040518082805190602001908083835b60208310151561017a5780518252602082019150602081019050602083039250610155565b6001836020036101000a0380198251168184511680821785525050505050509050019150509081526020016040518091039020549050919050565b806000836040518082805190602001908083835b6020831015156101ee57805182526020820191506020810190506020830392506101c9565b6001836020036101000a0380198251168184511680821785525050505050509050019150509081526020016040518091039020819055507f11fa40d38d8c12e6885f25dce1bff58b84fb756b4fbf3d70be7237df8c4569bc82826040518080602001838152602001828103825284818151815260200191508051906020019080838360005b8381101561028e578082015181840152602081019050610273565b50505050905090810190601f1680156102bb5780820380516001836020036101000a031916815260200191505b50935050505060405180910390a150505600a165627a7a72305820a7bd4530d4008911e0e21fee65b0d060ca18a1baff050318f117f181e7dab57a0029";
public static final String FUNC_RETURNBALANCE = "returnBalance";
public static final String FUNC_SETBALANCE = "setBalance";
public static final Event SETBALANCEEVENT_EVENT = new Event("setBalanceEvent",
Arrays.<TypeReference<?>>asList(new TypeReference<Utf8String>() {}, new TypeReference<Uint256>() {}));
;
protected Token(String contractAddress, Web3j web3j, Credentials credentials, BigInteger gasPrice, BigInteger gasLimit) {
super(BINARY, contractAddress, web3j, credentials, gasPrice, gasLimit);
}
protected Token(String contractAddress, Web3j web3j, TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit) {
super(BINARY, contractAddress, web3j, transactionManager, gasPrice, gasLimit);
}
public RemoteCall<BigInteger> returnBalance(String _name) {
final Function function = new Function(FUNC_RETURNBALANCE,
Arrays.<Type>asList(new org.web3j.abi.datatypes.Utf8String(_name)),
Arrays.<TypeReference<?>>asList(new TypeReference<Uint256>() {}));
return executeRemoteCallSingleValueReturn(function, BigInteger.class);
}
public RemoteCall<TransactionReceipt> setBalance(String _name, BigInteger _balance) {
final Function function = new Function(
FUNC_SETBALANCE,
Arrays.<Type>asList(new org.web3j.abi.datatypes.Utf8String(_name),
new org.web3j.abi.datatypes.generated.Uint256(_balance)),
Collections.<TypeReference<?>>emptyList());
return executeRemoteCallTransaction(function);
}
public List<SetBalanceEventEventResponse> getSetBalanceEventEvents(TransactionReceipt transactionReceipt) {
List<Contract.EventValuesWithLog> valueList = extractEventParametersWithLog(SETBALANCEEVENT_EVENT, transactionReceipt);
ArrayList<SetBalanceEventEventResponse> responses = new ArrayList<SetBalanceEventEventResponse>(valueList.size());
for (Contract.EventValuesWithLog eventValues : valueList) {
SetBalanceEventEventResponse typedResponse = new SetBalanceEventEventResponse();
typedResponse.log = eventValues.getLog();
typedResponse.name = (String) eventValues.getNonIndexedValues().get(0).getValue();
typedResponse.balance = (BigInteger) eventValues.getNonIndexedValues().get(1).getValue();
responses.add(typedResponse);
}
return responses;
}
public Observable<SetBalanceEventEventResponse> setBalanceEventEventObservable(EthFilter filter) {
return web3j.ethLogObservable(filter).map(new Func1<Log, SetBalanceEventEventResponse>() {
@Override
public SetBalanceEventEventResponse call(Log log) {
Contract.EventValuesWithLog eventValues = extractEventParametersWithLog(SETBALANCEEVENT_EVENT, log);
SetBalanceEventEventResponse typedResponse = new SetBalanceEventEventResponse();
typedResponse.log = log;
typedResponse.name = (String) eventValues.getNonIndexedValues().get(0).getValue();
typedResponse.balance = (BigInteger) eventValues.getNonIndexedValues().get(1).getValue();
return typedResponse;
}
});
}
public Observable<SetBalanceEventEventResponse> setBalanceEventEventObservable(DefaultBlockParameter startBlock, DefaultBlockParameter endBlock) {
EthFilter filter = new EthFilter(startBlock, endBlock, getContractAddress());
filter.addSingleTopic(EventEncoder.encode(SETBALANCEEVENT_EVENT));
return setBalanceEventEventObservable(filter);
}
public static RemoteCall<Token> deploy(Web3j web3j, Credentials credentials, BigInteger gasPrice, BigInteger gasLimit) {
return deployRemoteCall(Token.class, web3j, credentials, gasPrice, gasLimit, BINARY, "");
}
public static RemoteCall<Token> deploy(Web3j web3j, TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit) {
return deployRemoteCall(Token.class, web3j, transactionManager, gasPrice, gasLimit, BINARY, "");
}
public static Token load(String contractAddress, Web3j web3j, Credentials credentials, BigInteger gasPrice, BigInteger gasLimit) {
return new Token(contractAddress, web3j, credentials, gasPrice, gasLimit);
}
public static Token load(String contractAddress, Web3j web3j, TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit) {
return new Token(contractAddress, web3j, transactionManager, gasPrice, gasLimit);
}
public static class SetBalanceEventEventResponse {
public Log log;
public String name;
public BigInteger balance;
}
}
我們來看更清楚一下
Web3j web3 = Web3j.build(new HttpService()); // defaults to http://localhost:8545/
Web3ClientVersion web3ClientVersion = web3.web3ClientVersion().sendAsync().get();
String clientVersion = web3ClientVersion.getWeb3ClientVersion();
Credentials credentials = getCredentialsFromPrivateKeyAddress();
//登入
String deployedContract = deployContract(web3, credentials).toString();
//發布合約 hash
Token exampleContract = loadContract(deployedContract, web3, credentials);
// 讀入 合約
System.out.println("Deployed contract address; "+ deployedContract);
System.out.println("----------------------------------------");
//監聽器
activateFilter(web3, deployedContract ,exampleContract);
//調用 method
Boolean result = exampleContract.isValid();
System.out.println("ok"+result);
exampleContract.setBalance("Alice", BigInteger.valueOf(4)).send();
System.out.println("ok");
Object ans = exampleContract.returnBalance("Alice").send();
System.out.println("ok");
System.out.println("user-defined message: " + ans.toString());
ans = exampleContract.returnBalance("Bob").send();
System.out.println("user-defined message: " + ans.toString());
這邊要注意創世塊的問題也就是 gaslimt ,然後還有版本問題
web3j 3.5 這個版本 ,裡面函數也就是我們編譯出來的 智能合約
ethLogObservable
4.0後有發生過優化可能要調整一下 其他編譯軟體 的版本才可以兼容。
web3j 3.5 這個版本 ,裡面函數也就是我們編譯出來的 智能合約
ethLogObservable
4.0後有發生過優化可能要調整一下 其他編譯軟體 的版本才可以兼容。
啟動
成功!
後面應該會對這個合約再加強 一些東西 這個東西我就跟spring 放在一起了到現在我們已經產生一條私有鏈囉。
參考
https://stevenocean.github.io/2018/04/06/web3j-ethereum-token.html
參考
https://stevenocean.github.io/2018/04/06/web3j-ethereum-token.html