
org.bdware.client.SmartContractClient Maven / Gradle / Ivy
package org.bdware.client;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.bdware.client.ws.Action;
import org.bdware.client.ws.BaseClient;
import org.bouncycastle.crypto.CryptoException;
import org.bouncycastle.pqc.math.linearalgebra.ByteUtils;
import org.zz.gmhelper.SM2KeyPair;
import org.zz.gmhelper.SM2Util;
import javax.websocket.ClientEndpointConfig;
import javax.websocket.ContainerProvider;
import javax.websocket.DeploymentException;
import java.io.IOException;
import java.net.URI;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class SmartContractClient extends SmartContractHandler {
private static final Logger LOGGER = LogManager.getLogger(SmartContractClient.class);
public final ConcurrentHashMap cbs = new ConcurrentHashMap<>();
String uri;
BaseClient bc;
SM2KeyPair keyPair;
public SmartContractClient(String uri) {
this(uri, SM2Util.generateSM2KeyPair(null));
}
// ws://localhost:8080/SCIDE/SCExecutor
public SmartContractClient(String uri, SM2KeyPair pair) {
try {
keyPair = pair;
bc = new BaseClient(this);
this.uri = uri;
ContainerProvider.getWebSocketContainer()
.connectToServer(
bc, ClientEndpointConfig.Builder.create().build(), URI.create(uri));
} catch (DeploymentException | IOException e) {
e.printStackTrace();
System.err.println("[Connect failed]:" + uri);
}
}
public void listContractProcess() {
listContractProcess(null);
}
public void listContractProcess(ResultCallback rc) {
JsonObject jo = new JsonObject();
jo.addProperty("action", "listContractProcess");
// System.out.println("SendAction:" + jo.toString());
if (null != rc) {
cbs.put(this.uri, rc);
}
bc.sendText(jo.toString());
}
public void waitForConnect() {
while (!bc.connected()) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public SM2KeyPair getKeyPair() {
return keyPair;
}
@Override
public void onListContractProcess(JsonObject obj) {
info(obj.toString());
obj.addProperty("responseID", this.uri);
invokeCallback(obj);
}
@Override
public void onOutputStream(JsonObject obj) {
debug(obj.toString());
}
@Override
public void onStartContract(JsonObject obj) {
debug(obj.toString());
invokeCallback(obj);
}
@Override
public void onKillContractProcess(JsonObject obj) {
debug(obj.toString());
}
@Override
public void onHashResult(JsonObject obj) {
debug(obj.toString());
}
@Override
public void onKillAllContract(JsonObject obj) {
debug(obj.toString());
}
@Override
public void onExecuteResult(JsonObject obj) {
debug(obj.toString());
// !!!!!! Important, call this method to trigger callbacks
invokeCallback(obj);
}
protected void invokeCallback(JsonObject obj) {
if (obj.has("responseID")) {
String responseID = obj.get("responseID").getAsString();
if (cbs.containsKey(responseID)) {
synchronized (cbs.get(responseID)) {
ResultCallback rc = cbs.get(responseID);
cbs.remove(responseID);
rc.onResult(obj);
}
}
}
}
@Override
public void onUndefined(JsonObject obj) {
info(obj);
}
public void login() {
String msg = "{\"action\":\"getSessionID\"}";
bc.sendText(msg);
}
@Override
public void onSessionID(JsonObject obj) {
String session = obj.get("session").getAsString();
String msg = "{\"action\":\"login\",\"signature\":\"";
String signature = null;
try {
signature =
ByteUtils.toHexString(
SM2Util.sign(keyPair.getPrivateKeyParameter(), session.getBytes()));
} catch (CryptoException e) {
e.printStackTrace();
}
msg += signature;
msg += "\",\"pubKey\":\"" + keyPair.getPublicKeyStr() + "\"}";
debug("The second phase for login onGetNodeSession");
bc.sendText(msg);
}
@Override
public void onLogin(JsonObject obj) {
debug(obj.toString());
}
@Override
public void onLoadNodeConfig(JsonObject obj) {
ResultCallback cb = cbs.get("loadNodeConfig");
cbs.remove("loadNodeConfig");
cb.onResult(obj);
}
public void loadNodeConfig(ResultCallback cb) {
cbs.put("loadNodeConfig", null == cb ? this::info : cb);
sendMsg("{\"action\":\"loadNodeConfig\"}");
}
@Action
public void onException(JsonObject obj) {
debug(obj.toString());
}
public synchronized void sendMsg(String s) {
// System.out.println("SendAction:" + s);
bc.sendText(s);
}
public JsonObject executeContractSync(ContractRequest cr) {
String reqID = System.currentTimeMillis() + "_" + (int) (Math.random() * 10000);
Map req = fillReq(cr, reqID);
Result rc = new Result();
cbs.put(reqID, rc);
try {
sendMsg(new Gson().toJson(req));
while (!rc.hasResult()) {
Thread.yield();
}
return rc.result;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public void executeContract(ContractRequest cr) {
executeContract(cr, null);
}
public void executeContract(ContractRequest cr, ResultCallback rc) {
String reqID = System.currentTimeMillis() + "_" + (int) (Math.random() * 10000);
Map req = fillReq(cr, reqID);
if (rc != null) {
cbs.put(reqID, rc);
}
sendMsg(new Gson().toJson(req));
}
private Map fillReq(ContractRequest cr, String reqID) {
Map req = new HashMap<>();
req.put("action", "executeContract");
req.put("requestID", reqID);
req.put("contractID", cr.getContractID());
if (null == cr.getPublicKey()) {
cr.doSignature(keyPair);
}
req.put("signature", cr.signature);
req.put("pubkey", cr.getPublicKey());
req.put("operation", cr.getAction());
if (null == cr.getArg()) {
req.put("arg", "undefined");
} else {
if (cr.getArg().isJsonPrimitive())
req.put("arg", cr.getArg().getAsString());
else
req.put("arg", cr.getArg().toString());
}
return req;
}
public String getExecuteUrl(ContractRequest cr) {
return uri.replaceFirst("ws://", "http://")
.replaceFirst("/SCIDE/SCExecutor", "/SCIDE/CMManager?")
+ "action=executeContract"
+ "&contractID="
+ cr.getContractID()
+ "&pubkey="
+ cr.getPublicKey()
+ "&operation="
+ cr.getAction()
+ "&arg="
+ cr.getArg()
+ "&signature="
+ cr.signature;
}
public String getExecuteUrlNoSign(ContractRequest cr) {
return uri.replaceFirst("ws://", "http://")
.replaceFirst("/SCIDE/SCExecutor", "/SCIDE/CMManager")
+ "?action=executeContract"
+ "&contractID="
+ cr.getContractID()
+ "&operation="
+ cr.getAction()
+ "&arg="
+ cr.getArg();
}
public void setClusterAddress(String addr) {
String str = "{\"action\":\"changeNodeCenter\",\"data\":\"" + addr + "\"}";
sendMsg(str);
}
public void setName(String name) {
String str = "{\"action\":\"changeNodeName\",\"data\":\"" + name + "\"}";
sendMsg(str);
}
private void updateConfig(String key, String val) {
Map req = new HashMap<>();
req.put("action", "updateConfig");
req.put("key", key);
req.put("val", val);
sendMsg(new Gson().toJson(req));
}
public void setMasterAddress(String arg) {
updateConfig("masterAddress", arg);
}
public void setBDLedger(String arg) {
sendMsg("{\"action\":\"changeBDledger\",\"data\":\"" + arg + "\"}");
updateConfig("dataChain", arg);
}
private void debug(Object info) {
LOGGER.debug("[" + this.uri + "] " + info);
}
private void info(Object info) {
LOGGER.info("[" + this.uri + "] " + info);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy