| @@ -0,0 +1,112 @@ | |||||
| package com.jd.blockchain.contract.jvm; | |||||
| import java.lang.reflect.Method; | |||||
| import org.slf4j.Logger; | |||||
| import org.slf4j.LoggerFactory; | |||||
| import org.springframework.util.ReflectionUtils; | |||||
| import com.jd.blockchain.contract.ContractEventContext; | |||||
| import com.jd.blockchain.contract.ContractException; | |||||
| import com.jd.blockchain.contract.EventProcessingAware; | |||||
| import com.jd.blockchain.contract.engine.ContractCode; | |||||
| import com.jd.blockchain.utils.Bytes; | |||||
| /** | |||||
| * @author huanghaiquan | |||||
| * | |||||
| */ | |||||
| public abstract class AbstractContractCode implements ContractCode { | |||||
| private static final Logger LOGGER = LoggerFactory.getLogger(AbstractContractCode.class); | |||||
| private Bytes address; | |||||
| private long version; | |||||
| private ContractDefinition contractDefinition; | |||||
| public AbstractContractCode(Bytes address, long version, ContractDefinition contractDefinition) { | |||||
| this.address = address; | |||||
| this.version = version; | |||||
| this.contractDefinition = contractDefinition; | |||||
| } | |||||
| public ContractDefinition getContractDefinition() { | |||||
| return contractDefinition; | |||||
| } | |||||
| @Override | |||||
| public Bytes getAddress() { | |||||
| return address; | |||||
| } | |||||
| @Override | |||||
| public long getVersion() { | |||||
| return version; | |||||
| } | |||||
| @Override | |||||
| public byte[] processEvent(ContractEventContext eventContext) { | |||||
| EventProcessingAware evtProcAwire = null; | |||||
| Object retn = null; | |||||
| Exception error = null; | |||||
| try { | |||||
| // 执行预处理; | |||||
| Object contractInstance = getContractInstance(); | |||||
| if (contractInstance instanceof EventProcessingAware) { | |||||
| evtProcAwire = (EventProcessingAware) contractInstance; | |||||
| } | |||||
| if (evtProcAwire != null) { | |||||
| evtProcAwire.beforeEvent(eventContext); | |||||
| } | |||||
| // 反序列化参数; | |||||
| Method handleMethod = contractDefinition.getType().getHandleMethod(eventContext.getEvent()); | |||||
| if (handleMethod == null) { | |||||
| throw new ContractException( | |||||
| String.format("Contract[%s:%s] has no handle method to handle event[%s]!", address.toString(), | |||||
| contractDefinition.getType().getDeclaredClass().toString(), eventContext.getEvent())); | |||||
| } | |||||
| Object[] args = resolveArgs(); | |||||
| retn = ReflectionUtils.invokeMethod(handleMethod, contractInstance, args); | |||||
| } catch (Exception e) { | |||||
| error = e; | |||||
| } | |||||
| if (evtProcAwire != null) { | |||||
| try { | |||||
| evtProcAwire.postEvent(eventContext, error); | |||||
| } catch (Exception e) { | |||||
| String errorMessage = "Error occurred while posting contract event! --" + e.getMessage(); | |||||
| LOGGER.error(errorMessage, e); | |||||
| throw new ContractException(errorMessage, e); | |||||
| } | |||||
| } | |||||
| if (error != null) { | |||||
| // Rethrow error; | |||||
| throw new ContractException(String.format("Error occurred while processing event[%s] of contract[%s]! --%s", | |||||
| eventContext.getEvent(), address.toString(), error.getMessage()), error); | |||||
| } | |||||
| byte[] retnBytes = resolveResult(retn); | |||||
| return retnBytes; | |||||
| } | |||||
| protected abstract Object getContractInstance(); | |||||
| private byte[] resolveResult(Object retn) { | |||||
| if (retn == null) { | |||||
| return null; | |||||
| } | |||||
| // TODO: resolve result in bytes; | |||||
| throw new IllegalStateException("Not implemented!"); | |||||
| } | |||||
| private Object[] resolveArgs() { | |||||
| // TODO Auto-generated method stub | |||||
| throw new IllegalStateException("Not implemented!"); | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,24 @@ | |||||
| package com.jd.blockchain.contract.jvm; | |||||
| import com.jd.blockchain.contract.ContractType; | |||||
| public class ContractDefinition { | |||||
| private ContractType type; | |||||
| private Class<?> mainClass; | |||||
| public Class<?> getMainClass() { | |||||
| return mainClass; | |||||
| } | |||||
| public ContractType getType() { | |||||
| return type; | |||||
| } | |||||
| public ContractDefinition(ContractType type, Class<?> mainClass) { | |||||
| this.type = type; | |||||
| this.mainClass = mainClass; | |||||
| } | |||||
| } | |||||
| @@ -2,7 +2,6 @@ package com.jd.blockchain.contract.jvm; | |||||
| import com.jd.blockchain.contract.engine.ContractCode; | import com.jd.blockchain.contract.engine.ContractCode; | ||||
| import com.jd.blockchain.contract.engine.ContractEngine; | import com.jd.blockchain.contract.engine.ContractEngine; | ||||
| import com.jd.blockchain.ledger.BytesValue; | |||||
| import com.jd.blockchain.runtime.Module; | import com.jd.blockchain.runtime.Module; | ||||
| import com.jd.blockchain.runtime.RuntimeContext; | import com.jd.blockchain.runtime.RuntimeContext; | ||||
| import com.jd.blockchain.utils.Bytes; | import com.jd.blockchain.utils.Bytes; | ||||
| @@ -1,46 +1,57 @@ | |||||
| package com.jd.blockchain.contract.jvm; | package com.jd.blockchain.contract.jvm; | ||||
| import java.lang.reflect.Method; | |||||
| import java.util.concurrent.Callable; | import java.util.concurrent.Callable; | ||||
| import org.slf4j.Logger; | import org.slf4j.Logger; | ||||
| import org.slf4j.LoggerFactory; | import org.slf4j.LoggerFactory; | ||||
| import org.springframework.util.ReflectionUtils; | |||||
| import com.jd.blockchain.contract.Contract; | |||||
| import com.jd.blockchain.contract.ContractEventContext; | import com.jd.blockchain.contract.ContractEventContext; | ||||
| import com.jd.blockchain.contract.ContractException; | import com.jd.blockchain.contract.ContractException; | ||||
| import com.jd.blockchain.contract.EventProcessingAwire; | |||||
| import com.jd.blockchain.contract.engine.ContractCode; | |||||
| import com.jd.blockchain.contract.ContractType; | |||||
| import com.jd.blockchain.runtime.Module; | import com.jd.blockchain.runtime.Module; | ||||
| import com.jd.blockchain.transaction.ContractType; | |||||
| import com.jd.blockchain.utils.Bytes; | import com.jd.blockchain.utils.Bytes; | ||||
| /** | /** | ||||
| * contract code based jvm | |||||
| * 基于 java jar 包并且以模块化方式独立加载的合约代码; | |||||
| * | * | ||||
| * @author zhaogw | |||||
| * @author huanghaiquan | |||||
| * | |||||
| */ | */ | ||||
| public class JavaContractCode implements ContractCode { | |||||
| public class JavaContractCode extends AbstractContractCode { | |||||
| private static final Logger LOGGER = LoggerFactory.getLogger(JavaContractCode.class); | private static final Logger LOGGER = LoggerFactory.getLogger(JavaContractCode.class); | ||||
| private Module codeModule; | private Module codeModule; | ||||
| private Bytes address; | private Bytes address; | ||||
| private long version; | private long version; | ||||
| private Class<?> contractClass; | |||||
| private ContractType contractType; | |||||
| public JavaContractCode(Bytes address, long version, Module codeModule) { | public JavaContractCode(Bytes address, long version, Module codeModule) { | ||||
| super(address, version, resolveContractDefinition(codeModule)); | |||||
| this.address = address; | this.address = address; | ||||
| this.version = version; | this.version = version; | ||||
| this.codeModule = codeModule; | this.codeModule = codeModule; | ||||
| init(); | |||||
| } | } | ||||
| private void init() { | |||||
| String contractClassName = codeModule.getMainClass(); | |||||
| this.contractClass = codeModule.loadClass(contractClassName); | |||||
| this.contractType = ContractType.resolve(contractClass); | |||||
| protected static ContractDefinition resolveContractDefinition(Module codeModule) { | |||||
| String mainClassName = codeModule.getMainClass(); | |||||
| Class<?> mainClass = codeModule.loadClass(mainClassName); | |||||
| Class<?>[] interfaces = mainClass.getInterfaces(); | |||||
| Class<?> contractInterface = null; | |||||
| for (Class<?> itf : interfaces) { | |||||
| Contract annoContract = itf.getAnnotation(Contract.class); | |||||
| if (annoContract != null) { | |||||
| if (contractInterface == null) { | |||||
| contractInterface = itf; | |||||
| }else { | |||||
| throw new ContractException("One contract definition is only allowed to implement one contract type!"); | |||||
| } | |||||
| } | |||||
| } | |||||
| if (contractInterface == null) { | |||||
| throw new ContractException("No contract type is implemented!"); | |||||
| } | |||||
| ContractType type = ContractType.resolve(contractInterface); | |||||
| return new ContractDefinition(type, mainClass); | |||||
| } | } | ||||
| @Override | @Override | ||||
| @@ -58,8 +69,16 @@ public class JavaContractCode implements ContractCode { | |||||
| return codeModule.call(new ContractExecution(eventContext)); | return codeModule.call(new ContractExecution(eventContext)); | ||||
| } | } | ||||
| private class ContractExecution implements Callable<byte[]> { | |||||
| protected Object getContractInstance() { | |||||
| try { | |||||
| // 每一次调用都通过反射创建合约的实例; | |||||
| return getContractDefinition().getMainClass().newInstance(); | |||||
| } catch (InstantiationException | IllegalAccessException e) { | |||||
| throw new IllegalStateException(e.getMessage(), e); | |||||
| } | |||||
| } | |||||
| private class ContractExecution implements Callable<byte[]> { | |||||
| private ContractEventContext eventContext; | private ContractEventContext eventContext; | ||||
| public ContractExecution(ContractEventContext contractEventContext) { | public ContractExecution(ContractEventContext contractEventContext) { | ||||
| @@ -68,63 +87,7 @@ public class JavaContractCode implements ContractCode { | |||||
| @Override | @Override | ||||
| public byte[] call() throws Exception { | public byte[] call() throws Exception { | ||||
| EventProcessingAwire evtProcAwire = null; | |||||
| Object retn = null; | |||||
| Exception error = null; | |||||
| try { | |||||
| // 执行预处理; | |||||
| Object contractInstance = contractClass.newInstance();// 合约主类生成的类实例; | |||||
| if (contractInstance instanceof EventProcessingAwire) { | |||||
| evtProcAwire = (EventProcessingAwire) contractInstance; | |||||
| } | |||||
| if (evtProcAwire != null) { | |||||
| evtProcAwire.beforeEvent(eventContext); | |||||
| } | |||||
| // 反序列化参数; | |||||
| Method handleMethod = contractType.getHandleMethod(eventContext.getEvent()); | |||||
| if (handleMethod == null) { | |||||
| throw new ContractException( | |||||
| String.format("Contract[%s:%s] has no handle method to handle event[%s]!", | |||||
| address.toString(), contractClass.getName(), eventContext.getEvent())); | |||||
| } | |||||
| Object[] args = resolveArgs(); | |||||
| retn = ReflectionUtils.invokeMethod(handleMethod, contractInstance, args); | |||||
| } catch (Exception e) { | |||||
| error = e; | |||||
| } | |||||
| if (evtProcAwire != null) { | |||||
| try { | |||||
| evtProcAwire.postEvent(eventContext, error); | |||||
| } catch (Exception e) { | |||||
| LOGGER.error("Error occurred while posting contract event! --" + e.getMessage(), e); | |||||
| } | |||||
| } | |||||
| if (error != null) { | |||||
| // Rethrow error; | |||||
| throw error; | |||||
| } | |||||
| byte[] retnBytes = resolveResult(retn); | |||||
| return retnBytes; | |||||
| } | |||||
| private byte[] resolveResult(Object retn) { | |||||
| if (retn == null) { | |||||
| return null; | |||||
| } | |||||
| // TODO: resolve result in bytes; | |||||
| return null; | |||||
| } | |||||
| private Object[] resolveArgs() { | |||||
| // TODO Auto-generated method stub | |||||
| throw new IllegalStateException("Not implemented!"); | |||||
| return JavaContractCode.super.processEvent(eventContext); | |||||
| } | } | ||||
| } | } | ||||
| @@ -8,7 +8,7 @@ import com.github.javaparser.ast.PackageDeclaration; | |||||
| import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration; | import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration; | ||||
| import com.github.javaparser.ast.body.MethodDeclaration; | import com.github.javaparser.ast.body.MethodDeclaration; | ||||
| import com.github.javaparser.ast.visitor.VoidVisitorAdapter; | import com.github.javaparser.ast.visitor.VoidVisitorAdapter; | ||||
| import com.jd.blockchain.transaction.ContractType; | |||||
| import com.jd.blockchain.contract.ContractType; | |||||
| import com.jd.blockchain.utils.IllegalDataException; | import com.jd.blockchain.utils.IllegalDataException; | ||||
| import org.apache.maven.plugin.AbstractMojo; | import org.apache.maven.plugin.AbstractMojo; | ||||
| import org.apache.maven.plugin.MojoFailureException; | import org.apache.maven.plugin.MojoFailureException; | ||||
| @@ -4,7 +4,7 @@ import com.jd.blockchain.crypto.HashDigest; | |||||
| import com.jd.blockchain.ledger.KVDataEntry; | import com.jd.blockchain.ledger.KVDataEntry; | ||||
| @Contract | @Contract | ||||
| public class ReadContractImpl implements EventProcessingAwire, ReadContract { | |||||
| public class ReadContractImpl implements EventProcessingAware, ReadContract { | |||||
| private ContractEventContext eventContext; | private ContractEventContext eventContext; | ||||
| @@ -3,13 +3,9 @@ package com.jd.blockchain.ledger.core.impl; | |||||
| import java.util.ArrayList; | import java.util.ArrayList; | ||||
| import java.util.List; | import java.util.List; | ||||
| import javax.annotation.PostConstruct; | |||||
| import org.springframework.beans.factory.annotation.Autowired; | |||||
| import org.springframework.stereotype.Component; | import org.springframework.stereotype.Component; | ||||
| import com.jd.blockchain.ledger.LedgerException; | import com.jd.blockchain.ledger.LedgerException; | ||||
| import com.jd.blockchain.ledger.UserRegisterOperation; | |||||
| import com.jd.blockchain.ledger.core.OperationHandle; | import com.jd.blockchain.ledger.core.OperationHandle; | ||||
| import com.jd.blockchain.ledger.core.impl.handles.ContractCodeDeployOperationHandle; | import com.jd.blockchain.ledger.core.impl.handles.ContractCodeDeployOperationHandle; | ||||
| import com.jd.blockchain.ledger.core.impl.handles.ContractEventSendOperationHandle; | import com.jd.blockchain.ledger.core.impl.handles.ContractEventSendOperationHandle; | ||||
| @@ -2,8 +2,6 @@ package com.jd.blockchain.ledger.core.impl.handles; | |||||
| import static com.jd.blockchain.utils.BaseConstant.CONTRACT_SERVICE_PROVIDER; | import static com.jd.blockchain.utils.BaseConstant.CONTRACT_SERVICE_PROVIDER; | ||||
| import java.util.concurrent.CompletableFuture; | |||||
| import org.springframework.stereotype.Service; | import org.springframework.stereotype.Service; | ||||
| import com.jd.blockchain.contract.LocalContractEventContext; | import com.jd.blockchain.contract.LocalContractEventContext; | ||||
| @@ -1,82 +1,82 @@ | |||||
| //package test.com.jd.blockchain.ledger; | |||||
| // | |||||
| //import java.util.Map; | |||||
| //import java.util.concurrent.CompletableFuture; | |||||
| //import java.util.concurrent.ConcurrentHashMap; | |||||
| // | |||||
| //import com.jd.blockchain.contract.LocalContractEventContext; | |||||
| //import com.jd.blockchain.contract.engine.ContractCode; | |||||
| //import com.jd.blockchain.ledger.ContractEventSendOperation; | |||||
| //import com.jd.blockchain.ledger.LedgerException; | |||||
| //import com.jd.blockchain.ledger.Operation; | |||||
| //import com.jd.blockchain.ledger.core.ContractAccount; | |||||
| //import com.jd.blockchain.ledger.core.ContractAccountSet; | |||||
| //import com.jd.blockchain.ledger.core.LedgerDataSet; | |||||
| //import com.jd.blockchain.ledger.core.LedgerService; | |||||
| //import com.jd.blockchain.ledger.core.OperationHandle; | |||||
| //import com.jd.blockchain.ledger.core.TransactionRequestContext; | |||||
| //import com.jd.blockchain.ledger.core.impl.LedgerQueryService; | |||||
| //import com.jd.blockchain.ledger.core.impl.OperationHandleContext; | |||||
| //import com.jd.blockchain.ledger.core.impl.handles.ContractLedgerContext; | |||||
| //import com.jd.blockchain.utils.Bytes; | |||||
| // | |||||
| //public class ContractInvokingHandle implements OperationHandle { | |||||
| // | |||||
| // private Map<Bytes, Object> contractInstances = new ConcurrentHashMap<Bytes, Object>(); | |||||
| // | |||||
| // @Override | |||||
| // public byte[] process(Operation op, LedgerDataSet dataset, TransactionRequestContext requestContext, | |||||
| // LedgerDataSet previousBlockDataset, OperationHandleContext opHandleContext, LedgerService ledgerService) { | |||||
| // process(op, dataset, requestContext, previousBlockDataset, opHandleContext, ledgerService, null); | |||||
| // | |||||
| // // TODO: return value; | |||||
| // return null; | |||||
| // } | |||||
| // | |||||
| // @Override | |||||
| // public boolean support(Class<?> operationType) { | |||||
| // return ContractEventSendOperation.class.isAssignableFrom(operationType); | |||||
| // } | |||||
| // | |||||
| // public void process(Operation op, LedgerDataSet dataset, TransactionRequestContext requestContext, | |||||
| // LedgerDataSet previousBlockDataset, OperationHandleContext opHandleContext, LedgerService ledgerService, | |||||
| // CompletableFuture<String> contractReturn) { | |||||
| // | |||||
| // ContractEventSendOperation contractOP = (ContractEventSendOperation) op; | |||||
| // // 先从账本校验合约的有效性; | |||||
| // // 注意:必须在前一个区块的数据集中进行校验,因为那是经过共识的数据;从当前新区块链数据集校验则会带来攻击风险:未经共识的合约得到执行; | |||||
| // ContractAccountSet contractSet = previousBlockDataset.getContractAccountSet(); | |||||
| // if (!contractSet.contains(contractOP.getContractAddress())) { | |||||
| // throw new LedgerException(String.format("Contract was not registered! --[ContractAddress=%s]", | |||||
| // contractOP.getContractAddress())); | |||||
| // } | |||||
| // | |||||
| // // 创建合约的账本上下文实例; | |||||
| // LedgerQueryService queryService = new LedgerQueryService(ledgerService); | |||||
| // ContractLedgerContext ledgerContext = new ContractLedgerContext(queryService, opHandleContext); | |||||
| // | |||||
| // // 先检查合约引擎是否已经加载合约;如果未加载,再从账本中读取合约代码并装载到引擎中执行; | |||||
| // ContractAccount contract = contractSet.getContract(contractOP.getContractAddress()); | |||||
| // if (contract == null) { | |||||
| // throw new LedgerException(String.format("Contract was not registered! --[ContractAddress=%s]", | |||||
| // contractOP.getContractAddress())); | |||||
| // } | |||||
| // | |||||
| // // 创建合约上下文; | |||||
| // LocalContractEventContext localContractEventContext = new LocalContractEventContext( | |||||
| // requestContext.getRequest().getTransactionContent().getLedgerHash(), contractOP.getEvent()); | |||||
| // localContractEventContext.setArgs(contractOP.getArgs()).setTransactionRequest(requestContext.getRequest()) | |||||
| // .setLedgerContext(ledgerContext); | |||||
| // | |||||
| // ContractCode contractCode = JVM_ENGINE.getContract(contract.getAddress(), contract.getChaincodeVersion()); | |||||
| // if (contractCode == null) { | |||||
| // // 装载合约; | |||||
| // contractCode = JVM_ENGINE.setupContract(contract.getAddress(), contract.getChaincodeVersion(), | |||||
| // contract.getChainCode()); | |||||
| // } | |||||
| // | |||||
| // // 处理合约事件; | |||||
| // contractCode.processEvent(localContractEventContext, contractReturn); | |||||
| // } | |||||
| // | |||||
| //} | |||||
| package test.com.jd.blockchain.ledger; | |||||
| import java.util.Map; | |||||
| import java.util.concurrent.CompletableFuture; | |||||
| import java.util.concurrent.ConcurrentHashMap; | |||||
| import com.jd.blockchain.contract.LocalContractEventContext; | |||||
| import com.jd.blockchain.contract.engine.ContractCode; | |||||
| import com.jd.blockchain.ledger.ContractEventSendOperation; | |||||
| import com.jd.blockchain.ledger.LedgerException; | |||||
| import com.jd.blockchain.ledger.Operation; | |||||
| import com.jd.blockchain.ledger.core.ContractAccount; | |||||
| import com.jd.blockchain.ledger.core.ContractAccountSet; | |||||
| import com.jd.blockchain.ledger.core.LedgerDataSet; | |||||
| import com.jd.blockchain.ledger.core.LedgerService; | |||||
| import com.jd.blockchain.ledger.core.OperationHandle; | |||||
| import com.jd.blockchain.ledger.core.TransactionRequestContext; | |||||
| import com.jd.blockchain.ledger.core.impl.LedgerQueryService; | |||||
| import com.jd.blockchain.ledger.core.impl.OperationHandleContext; | |||||
| import com.jd.blockchain.ledger.core.impl.handles.ContractLedgerContext; | |||||
| import com.jd.blockchain.utils.Bytes; | |||||
| public class ContractInvokingHandle implements OperationHandle { | |||||
| private Map<Bytes, Object> contractInstances = new ConcurrentHashMap<Bytes, Object>(); | |||||
| @Override | |||||
| public byte[] process(Operation op, LedgerDataSet dataset, TransactionRequestContext requestContext, | |||||
| LedgerDataSet previousBlockDataset, OperationHandleContext opHandleContext, LedgerService ledgerService) { | |||||
| process(op, dataset, requestContext, previousBlockDataset, opHandleContext, ledgerService, null); | |||||
| // TODO: return value; | |||||
| return null; | |||||
| } | |||||
| @Override | |||||
| public boolean support(Class<?> operationType) { | |||||
| return ContractEventSendOperation.class.isAssignableFrom(operationType); | |||||
| } | |||||
| public void process(Operation op, LedgerDataSet dataset, TransactionRequestContext requestContext, | |||||
| LedgerDataSet previousBlockDataset, OperationHandleContext opHandleContext, LedgerService ledgerService, | |||||
| CompletableFuture<String> contractReturn) { | |||||
| ContractEventSendOperation contractOP = (ContractEventSendOperation) op; | |||||
| // 先从账本校验合约的有效性; | |||||
| // 注意:必须在前一个区块的数据集中进行校验,因为那是经过共识的数据;从当前新区块链数据集校验则会带来攻击风险:未经共识的合约得到执行; | |||||
| ContractAccountSet contractSet = previousBlockDataset.getContractAccountSet(); | |||||
| if (!contractSet.contains(contractOP.getContractAddress())) { | |||||
| throw new LedgerException(String.format("Contract was not registered! --[ContractAddress=%s]", | |||||
| contractOP.getContractAddress())); | |||||
| } | |||||
| // 创建合约的账本上下文实例; | |||||
| LedgerQueryService queryService = new LedgerQueryService(ledgerService); | |||||
| ContractLedgerContext ledgerContext = new ContractLedgerContext(queryService, opHandleContext); | |||||
| // 先检查合约引擎是否已经加载合约;如果未加载,再从账本中读取合约代码并装载到引擎中执行; | |||||
| ContractAccount contract = contractSet.getContract(contractOP.getContractAddress()); | |||||
| if (contract == null) { | |||||
| throw new LedgerException(String.format("Contract was not registered! --[ContractAddress=%s]", | |||||
| contractOP.getContractAddress())); | |||||
| } | |||||
| // 创建合约上下文; | |||||
| LocalContractEventContext localContractEventContext = new LocalContractEventContext( | |||||
| requestContext.getRequest().getTransactionContent().getLedgerHash(), contractOP.getEvent()); | |||||
| localContractEventContext.setArgs(contractOP.getArgs()).setTransactionRequest(requestContext.getRequest()) | |||||
| .setLedgerContext(ledgerContext); | |||||
| ContractCode contractCode = JVM_ENGINE.getContract(contract.getAddress(), contract.getChaincodeVersion()); | |||||
| if (contractCode == null) { | |||||
| // 装载合约; | |||||
| contractCode = JVM_ENGINE.setupContract(contract.getAddress(), contract.getChaincodeVersion(), | |||||
| contract.getChainCode()); | |||||
| } | |||||
| // 处理合约事件; | |||||
| contractCode.processEvent(localContractEventContext, contractReturn); | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,49 @@ | |||||
| package test.com.jd.blockchain.ledger; | |||||
| public interface TestContractImpl { | |||||
| /** | |||||
| * 发行资产; | |||||
| * | |||||
| * @param asset 资产代码; | |||||
| * @param amount 本次发行的资产数量; | |||||
| * @return 资产总量; | |||||
| */ | |||||
| long issue(String asset, long amount); | |||||
| /** | |||||
| * 获取资产总量; | |||||
| * | |||||
| * @param asset | |||||
| * @return | |||||
| */ | |||||
| long getAmount(String asset); | |||||
| /** | |||||
| * 获取资产余额; | |||||
| * | |||||
| * @param address | |||||
| * @param asset | |||||
| * @return | |||||
| */ | |||||
| long getBalance(String address, String asset); | |||||
| /** | |||||
| * 向账户分配资产; | |||||
| * | |||||
| * @param address | |||||
| * @param asset | |||||
| * @param amount | |||||
| */ | |||||
| void assign(String address, String asset, int amount); | |||||
| /** | |||||
| * 转移资产; | |||||
| * | |||||
| * @param fromAddress | |||||
| * @param toAddress | |||||
| * @param asset | |||||
| * @param amount | |||||
| */ | |||||
| void transfer(String fromAddress, String toAddress, String asset, long amount); | |||||
| } | |||||
| @@ -0,0 +1,11 @@ | |||||
| package com.jd.blockchain.contract; | |||||
| /** | |||||
| * 合约实现 {@link ContractAware} 的子接口可以监听运行时的生命周期事件; | |||||
| * | |||||
| * @author huanghaiquan | |||||
| * | |||||
| */ | |||||
| public interface ContractAware { | |||||
| } | |||||
| @@ -1,18 +1,17 @@ | |||||
| package com.jd.blockchain.contract; | package com.jd.blockchain.contract; | ||||
| public class ContractException extends RuntimeException { | |||||
| private static final long serialVersionUID = 4338023105616639257L; | |||||
| import com.jd.blockchain.ledger.LedgerException; | |||||
| public class ContractException extends LedgerException { | |||||
| private static final long serialVersionUID = -4643365435848655115L; | |||||
| public ContractException(String message) { | public ContractException(String message) { | ||||
| super(message); | super(message); | ||||
| } | } | ||||
| public ContractException(String message,ErrorCodeEnum errorCodeEnum) { | |||||
| super(message+","+errorCodeEnum.toString()); | |||||
| public ContractException(String message, Throwable cause) { | |||||
| super(message, cause); | |||||
| } | } | ||||
| public ContractException(ErrorCodeEnum errorCodeEnum) { | |||||
| super(errorCodeEnum.toString()); | |||||
| } | |||||
| } | } | ||||
| @@ -7,7 +7,7 @@ package com.jd.blockchain.contract; | |||||
| * @author huanghaiquan | * @author huanghaiquan | ||||
| * | * | ||||
| */ | */ | ||||
| public interface ContractAppLifecycleAwire extends ContractRuntimeAwire { | |||||
| public interface ContractLifecycleAware extends ContractAware { | |||||
| void postConstruct(); | void postConstruct(); | ||||
| @@ -1,11 +0,0 @@ | |||||
| package com.jd.blockchain.contract; | |||||
| /** | |||||
| * 合约实现 {@link ContractRuntimeAwire} 的子接口可以监听运行时的生命周期事件; | |||||
| * | |||||
| * @author huanghaiquan | |||||
| * | |||||
| */ | |||||
| public interface ContractRuntimeAwire { | |||||
| } | |||||
| @@ -1,4 +1,4 @@ | |||||
| package com.jd.blockchain.transaction; | |||||
| package com.jd.blockchain.contract; | |||||
| import java.lang.annotation.Annotation; | import java.lang.annotation.Annotation; | ||||
| import java.lang.reflect.Method; | import java.lang.reflect.Method; | ||||
| @@ -8,9 +8,6 @@ import java.util.List; | |||||
| import java.util.Map; | import java.util.Map; | ||||
| import java.util.Set; | import java.util.Set; | ||||
| import com.jd.blockchain.contract.Contract; | |||||
| import com.jd.blockchain.contract.ContractEvent; | |||||
| import com.jd.blockchain.contract.ContractException; | |||||
| import com.jd.blockchain.utils.IllegalDataException; | import com.jd.blockchain.utils.IllegalDataException; | ||||
| public class ContractType { | public class ContractType { | ||||
| @@ -18,7 +15,16 @@ public class ContractType { | |||||
| private String name; | private String name; | ||||
| private Map<String, Method> events = new HashMap<>(); | private Map<String, Method> events = new HashMap<>(); | ||||
| private Map<Method, String> handleMethods = new HashMap<>(); | private Map<Method, String> handleMethods = new HashMap<>(); | ||||
| // private Map<Method, List<DataContract>> dataContractMap = new HashMap<>(); | |||||
| private Class<?> declaredClass; | |||||
| public String getName() { | |||||
| return name; | |||||
| } | |||||
| public Class<?> getDeclaredClass() { | |||||
| return declaredClass; | |||||
| } | |||||
| /** | /** | ||||
| * 返回声明的所有事件; | * 返回声明的所有事件; | ||||
| @@ -29,10 +35,6 @@ public class ContractType { | |||||
| return events.keySet(); | return events.keySet(); | ||||
| } | } | ||||
| // public Map<Method, List<DataContract>> getDataContractMap() { | |||||
| // return dataContractMap; | |||||
| // } | |||||
| /** | /** | ||||
| * 返回指定方法声明的事件;<br> | * 返回指定方法声明的事件;<br> | ||||
| * | * | ||||
| @@ -60,32 +62,39 @@ public class ContractType { | |||||
| private ContractType() { | private ContractType() { | ||||
| } | } | ||||
| public static ContractType resolve(Class<?> contractIntf){ | |||||
| /** | |||||
| * 解析合约的声明; | |||||
| * | |||||
| * @param contractDelaredInterface 声明合约的接口类型; | |||||
| * @return | |||||
| */ | |||||
| public static ContractType resolve(Class<?> contractDelaredInterface) { | |||||
| ContractType contractType = new ContractType(); | ContractType contractType = new ContractType(); | ||||
| Annotation annotation = contractIntf.getDeclaredAnnotation(Contract.class); | |||||
| Annotation annotation = contractDelaredInterface.getDeclaredAnnotation(Contract.class); | |||||
| //contains: @Contract? | |||||
| // contains: @Contract? | |||||
| boolean isContractType = annotation != null ? true : false; | boolean isContractType = annotation != null ? true : false; | ||||
| if(!isContractType){ | |||||
| if (!isContractType) { | |||||
| throw new IllegalDataException("is not Contract Type, becaust there is not @Contract."); | throw new IllegalDataException("is not Contract Type, becaust there is not @Contract."); | ||||
| } | } | ||||
| //contractIntf contains @Contract and @ContractEvent; | |||||
| Method[] classMethods = contractIntf.getDeclaredMethods(); | |||||
| // contractIntf contains @Contract and @ContractEvent; | |||||
| Method[] classMethods = contractDelaredInterface.getDeclaredMethods(); | |||||
| for (Method method : classMethods) { | for (Method method : classMethods) { | ||||
| // if current method contains @ContractEvent,then put it in this map; | // if current method contains @ContractEvent,then put it in this map; | ||||
| ContractEvent contractEvent = method.getAnnotation(ContractEvent.class); | ContractEvent contractEvent = method.getAnnotation(ContractEvent.class); | ||||
| if (contractEvent != null) { | if (contractEvent != null) { | ||||
| String eventName_ = contractEvent.name(); | String eventName_ = contractEvent.name(); | ||||
| //if annoMethodMap has contained the eventName, too many same eventNames exists probably, say NO! | |||||
| if(contractType.events.containsKey(eventName_)){ | |||||
| // if annoMethodMap has contained the eventName, too many same eventNames exists | |||||
| // probably, say NO! | |||||
| if (contractType.events.containsKey(eventName_)) { | |||||
| throw new ContractException("there is repeat definition of contractEvent to @ContractEvent."); | throw new ContractException("there is repeat definition of contractEvent to @ContractEvent."); | ||||
| } | } | ||||
| //check param's type is fit for need. | |||||
| // check param's type is fit for need. | |||||
| Class<?>[] paramTypes = method.getParameterTypes(); | Class<?>[] paramTypes = method.getParameterTypes(); | ||||
| List dataContractList = new ArrayList(); | List dataContractList = new ArrayList(); | ||||
| for(Class<?> curParamType : paramTypes){ | |||||
| for (Class<?> curParamType : paramTypes) { | |||||
| throw new IllegalStateException("Not implemented!"); | throw new IllegalStateException("Not implemented!"); | ||||
| // DataContract dataContract = ContractSerializeUtils.parseDataContract(curParamType); | // DataContract dataContract = ContractSerializeUtils.parseDataContract(curParamType); | ||||
| // dataContractList.add(dataContract); | // dataContractList.add(dataContract); | ||||
| @@ -95,18 +104,9 @@ public class ContractType { | |||||
| // } | // } | ||||
| contractType.events.put(eventName_, method); | contractType.events.put(eventName_, method); | ||||
| contractType.handleMethods.put(method,eventName_); | |||||
| contractType.handleMethods.put(method, eventName_); | |||||
| } | } | ||||
| } | } | ||||
| return contractType; | return contractType; | ||||
| } | } | ||||
| @Override | |||||
| public String toString() { | |||||
| return "ContractType{" + | |||||
| "name='" + name + '\'' + | |||||
| ", events=" + events + | |||||
| ", handleMethods=" + handleMethods + | |||||
| '}'; | |||||
| } | |||||
| } | } | ||||
| @@ -1,52 +0,0 @@ | |||||
| package com.jd.blockchain.contract; | |||||
| /** | |||||
| * 给每个错误编码,编译快速定位; | |||||
| * @Author zhaogw | |||||
| * @Date 2018/11/8 15:32 | |||||
| */ | |||||
| public enum ErrorCodeEnum { | |||||
| //<100为致命错误; | |||||
| GATEWAY_CONNECT_ERROR(1,ErrorType.ERROR,"GatewayServiceFactory connect error.!"), | |||||
| CONTRACT_CLASSPATH_NOT_SET(2,ErrorType.ERROR,"in private contract classLoader,no jar in the contract folder!"), | |||||
| //其它错误从101开始计数; | |||||
| AMOUNT_NEGATIVE(101,ErrorType.ALARM,"The amount is negative!"); | |||||
| private int code; | |||||
| private int type; | |||||
| private String message; | |||||
| ErrorCodeEnum(int code, int type, String message) { | |||||
| this.code = code; | |||||
| this.type = type; | |||||
| this.message = message; | |||||
| } | |||||
| public int getCode() { | |||||
| return code; | |||||
| } | |||||
| public int getType() { | |||||
| return type; | |||||
| } | |||||
| public String getMessage() { | |||||
| return message; | |||||
| } | |||||
| @Override | |||||
| public String toString(){ | |||||
| return "code:"+code+", type:"+type+", message:"+message; | |||||
| } | |||||
| } | |||||
| /** | |||||
| * 给错误分个类,便于汇总; | |||||
| */ | |||||
| class ErrorType { | |||||
| public static final int ALARM = 0; | |||||
| public static final int ERROR = 1; | |||||
| public static final int CONTRACT_EXE = 2; | |||||
| public static final int CONTRACT_COMPILE = 3; | |||||
| } | |||||
| @@ -4,7 +4,7 @@ package com.jd.blockchain.contract; | |||||
| * @author huanghaiquan | * @author huanghaiquan | ||||
| * | * | ||||
| */ | */ | ||||
| public interface EventProcessingAwire extends ContractRuntimeAwire { | |||||
| public interface EventProcessingAware extends ContractAware { | |||||
| /** | /** | ||||
| * 在事件处理方法执行之前调用; | * 在事件处理方法执行之前调用; | ||||
| @@ -13,17 +13,14 @@ import com.jd.blockchain.ledger.TransactionRequest; | |||||
| public class LocalContractEventContext implements ContractEventContext,Cloneable { | public class LocalContractEventContext implements ContractEventContext,Cloneable { | ||||
| private HashDigest ledgeHash; | private HashDigest ledgeHash; | ||||
| private String event; | private String event; | ||||
| private byte[] chainCode; | |||||
| private byte[] args; | private byte[] args; | ||||
| private TransactionRequest transactionRequest; | private TransactionRequest transactionRequest; | ||||
| private Set<BlockchainIdentity> txSigners; | private Set<BlockchainIdentity> txSigners; | ||||
| private Set<BlockchainIdentity> contractOwners; | |||||
| private LedgerContext ledgerContext; | private LedgerContext ledgerContext; | ||||
| public LocalContractEventContext(HashDigest ledgeHash, String event){ | public LocalContractEventContext(HashDigest ledgeHash, String event){ | ||||
| this.ledgeHash = ledgeHash; | this.ledgeHash = ledgeHash; | ||||
| this.event = event; | this.event = event; | ||||
| // this.chainCode = chainCode; | |||||
| } | } | ||||
| @Override | @Override | ||||
| @@ -81,11 +78,6 @@ public class LocalContractEventContext implements ContractEventContext,Cloneable | |||||
| return this; | return this; | ||||
| } | } | ||||
| public LocalContractEventContext setContractOwners(Set<BlockchainIdentity> contractOwners) { | |||||
| this.contractOwners = contractOwners; | |||||
| return this; | |||||
| } | |||||
| public LocalContractEventContext setLedgerContext(LedgerContext ledgerContext) { | public LocalContractEventContext setLedgerContext(LedgerContext ledgerContext) { | ||||
| this.ledgerContext = ledgerContext; | this.ledgerContext = ledgerContext; | ||||
| return this; | return this; | ||||
| @@ -3,6 +3,7 @@ package com.jd.blockchain.transaction; | |||||
| import java.lang.reflect.InvocationHandler; | import java.lang.reflect.InvocationHandler; | ||||
| import java.lang.reflect.Method; | import java.lang.reflect.Method; | ||||
| import com.jd.blockchain.contract.ContractType; | |||||
| import com.jd.blockchain.utils.Bytes; | import com.jd.blockchain.utils.Bytes; | ||||
| import com.jd.blockchain.utils.IllegalDataException; | import com.jd.blockchain.utils.IllegalDataException; | ||||
| @@ -6,6 +6,7 @@ import java.util.Map; | |||||
| import java.util.concurrent.ConcurrentHashMap; | import java.util.concurrent.ConcurrentHashMap; | ||||
| import com.jd.blockchain.contract.Contract; | import com.jd.blockchain.contract.Contract; | ||||
| import com.jd.blockchain.contract.ContractType; | |||||
| import com.jd.blockchain.utils.Bytes; | import com.jd.blockchain.utils.Bytes; | ||||
| public class ContractInvocationProxyBuilder { | public class ContractInvocationProxyBuilder { | ||||
| @@ -0,0 +1,59 @@ | |||||
| package test.com.jd.blockchain.ledger.data; | |||||
| import static org.junit.Assert.assertEquals; | |||||
| import static org.junit.Assert.assertNotNull; | |||||
| import static org.junit.Assert.assertNull; | |||||
| import static org.junit.Assert.assertTrue; | |||||
| import java.lang.reflect.Method; | |||||
| import java.util.Set; | |||||
| import org.junit.Test; | |||||
| import com.jd.blockchain.contract.ContractType; | |||||
| public class ContractTypeTest { | |||||
| /** | |||||
| * 正常测试; | |||||
| * @throws SecurityException | |||||
| * @throws NoSuchMethodException | |||||
| */ | |||||
| @Test | |||||
| public void normalTest() throws NoSuchMethodException, SecurityException { | |||||
| ContractType contractType = ContractType.resolve(NormalContract.class); | |||||
| assertEquals(NormalContract.class, contractType.getDeclaredClass()); | |||||
| assertEquals("NORMAL-CONTRACT", contractType.getName()); | |||||
| Set<String> events = contractType.getEvents(); | |||||
| assertEquals(5, events.size()); | |||||
| assertTrue(events.contains("issue")); | |||||
| assertTrue(events.contains("get_amount")); | |||||
| assertTrue(events.contains("get_balance")); | |||||
| assertTrue(events.contains("assign")); | |||||
| assertTrue(events.contains("transfer")); | |||||
| Method issueMethod = contractType.getHandleMethod("issue"); | |||||
| assertNotNull(issueMethod); | |||||
| Method getAmountMethod = contractType.getHandleMethod("get_amount"); | |||||
| assertNotNull(getAmountMethod); | |||||
| Method getBalanceMethod = contractType.getHandleMethod("get_balance"); | |||||
| assertNotNull(getBalanceMethod); | |||||
| Method assignMethod = contractType.getHandleMethod("assign"); | |||||
| assertNotNull(assignMethod); | |||||
| Method transferMethod = contractType.getHandleMethod("transfer"); | |||||
| assertNotNull(transferMethod); | |||||
| assertEquals("issue", contractType.getEvent(issueMethod)); | |||||
| assertEquals("get_amount", contractType.getEvent(getAmountMethod)); | |||||
| assertEquals("get_balance", contractType.getEvent(getBalanceMethod)); | |||||
| assertEquals("assign", contractType.getEvent(assignMethod)); | |||||
| assertEquals("transfer", contractType.getEvent(transferMethod)); | |||||
| Method toStringMethod = NormalContractImpl.class.getMethod("toString"); | |||||
| assertNull(contractType.getEvent(toStringMethod)); | |||||
| assertNull(contractType.getHandleMethod("NotExist")); | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,58 @@ | |||||
| package test.com.jd.blockchain.ledger.data; | |||||
| import com.jd.blockchain.contract.Contract; | |||||
| import com.jd.blockchain.contract.ContractEvent; | |||||
| @Contract(name="NORMAL-CONTRACT") | |||||
| public interface NormalContract { | |||||
| /** | |||||
| * 发行资产; | |||||
| * | |||||
| * @param asset 资产代码; | |||||
| * @param amount 本次发行的资产数量; | |||||
| * @return 资产总量; | |||||
| */ | |||||
| @ContractEvent(name="issue") | |||||
| long issue(String asset, long amount); | |||||
| /** | |||||
| * 获取资产总量; | |||||
| * | |||||
| * @param asset | |||||
| * @return | |||||
| */ | |||||
| @ContractEvent(name="get_amount") | |||||
| long getAmount(String asset); | |||||
| /** | |||||
| * 获取资产余额; | |||||
| * | |||||
| * @param address | |||||
| * @param asset | |||||
| * @return | |||||
| */ | |||||
| @ContractEvent(name="get_balance") | |||||
| long getBalance(String address, String asset); | |||||
| /** | |||||
| * 向账户分配资产; | |||||
| * | |||||
| * @param address | |||||
| * @param asset | |||||
| * @param amount | |||||
| */ | |||||
| @ContractEvent(name="assign") | |||||
| void assign(String address, String asset, int amount); | |||||
| /** | |||||
| * 转移资产; | |||||
| * | |||||
| * @param fromAddress | |||||
| * @param toAddress | |||||
| * @param asset | |||||
| * @param amount | |||||
| */ | |||||
| @ContractEvent(name="transfer") | |||||
| void transfer(String fromAddress, String toAddress, String asset, long amount); | |||||
| } | |||||
| @@ -0,0 +1,35 @@ | |||||
| package test.com.jd.blockchain.ledger.data; | |||||
| public class NormalContractImpl implements NormalContract{ | |||||
| @Override | |||||
| public long issue(String asset, long amount) { | |||||
| // TODO Auto-generated method stub | |||||
| return 0; | |||||
| } | |||||
| @Override | |||||
| public long getAmount(String asset) { | |||||
| // TODO Auto-generated method stub | |||||
| return 0; | |||||
| } | |||||
| @Override | |||||
| public long getBalance(String address, String asset) { | |||||
| // TODO Auto-generated method stub | |||||
| return 0; | |||||
| } | |||||
| @Override | |||||
| public void assign(String address, String asset, int amount) { | |||||
| // TODO Auto-generated method stub | |||||
| } | |||||
| @Override | |||||
| public void transfer(String fromAddress, String toAddress, String asset, long amount) { | |||||
| // TODO Auto-generated method stub | |||||
| } | |||||
| } | |||||
| @@ -131,17 +131,17 @@ public abstract class RuntimeContext { | |||||
| private ClassLoader moduleClassLoader; | private ClassLoader moduleClassLoader; | ||||
| private String MainClass; | |||||
| private String mainClass; | |||||
| public DefaultModule(String name, ClassLoader cl, String mainClass) { | public DefaultModule(String name, ClassLoader cl, String mainClass) { | ||||
| this.name = name; | this.name = name; | ||||
| this.moduleClassLoader = cl; | this.moduleClassLoader = cl; | ||||
| this.MainClass = mainClass; | |||||
| this.mainClass = mainClass; | |||||
| } | } | ||||
| @Override | @Override | ||||
| public String getMainClass() { | public String getMainClass() { | ||||
| return MainClass; | |||||
| return mainClass; | |||||
| } | } | ||||
| @@ -6,7 +6,7 @@ import java.util.Set; | |||||
| import com.jd.blockchain.contract.ContractEventContext; | import com.jd.blockchain.contract.ContractEventContext; | ||||
| import com.jd.blockchain.contract.ContractException; | import com.jd.blockchain.contract.ContractException; | ||||
| import com.jd.blockchain.contract.EventProcessingAwire; | |||||
| import com.jd.blockchain.contract.EventProcessingAware; | |||||
| import com.jd.blockchain.crypto.HashDigest; | import com.jd.blockchain.crypto.HashDigest; | ||||
| import com.jd.blockchain.ledger.BlockchainIdentity; | import com.jd.blockchain.ledger.BlockchainIdentity; | ||||
| import com.jd.blockchain.ledger.KVDataEntry; | import com.jd.blockchain.ledger.KVDataEntry; | ||||
| @@ -21,7 +21,7 @@ import com.jd.blockchain.ledger.KVDataObject; | |||||
| * @author huanghaiquan | * @author huanghaiquan | ||||
| * | * | ||||
| */ | */ | ||||
| public class AssetContractImpl implements EventProcessingAwire, AssetContract { | |||||
| public class AssetContractImpl implements EventProcessingAware, AssetContract { | |||||
| // 资产管理账户的地址; | // 资产管理账户的地址; | ||||
| private static final String ASSET_ADDRESS = "2njZBNbFQcmKd385DxVejwSjy4driRzf9Pk"; | private static final String ASSET_ADDRESS = "2njZBNbFQcmKd385DxVejwSjy4driRzf9Pk"; | ||||
| // 保存资产总数的键; | // 保存资产总数的键; | ||||
| @@ -2,11 +2,11 @@ package com.jd.blockchain.mocker.contracts; | |||||
| import com.jd.blockchain.contract.ContractEventContext; | import com.jd.blockchain.contract.ContractEventContext; | ||||
| import com.jd.blockchain.contract.ContractException; | import com.jd.blockchain.contract.ContractException; | ||||
| import com.jd.blockchain.contract.EventProcessingAwire; | |||||
| import com.jd.blockchain.contract.EventProcessingAware; | |||||
| import com.jd.blockchain.crypto.HashDigest; | import com.jd.blockchain.crypto.HashDigest; | ||||
| import com.jd.blockchain.ledger.KVDataEntry; | import com.jd.blockchain.ledger.KVDataEntry; | ||||
| public class AccountContractImpl implements EventProcessingAwire, AccountContract { | |||||
| public class AccountContractImpl implements EventProcessingAware, AccountContract { | |||||
| private ContractEventContext eventContext; | private ContractEventContext eventContext; | ||||
| @@ -2,9 +2,9 @@ package com.jd.blockchain.mocker.contracts; | |||||
| import com.jd.blockchain.contract.ContractEventContext; | import com.jd.blockchain.contract.ContractEventContext; | ||||
| import com.jd.blockchain.contract.ContractException; | import com.jd.blockchain.contract.ContractException; | ||||
| import com.jd.blockchain.contract.EventProcessingAwire; | |||||
| import com.jd.blockchain.contract.EventProcessingAware; | |||||
| public class WriteContractImpl implements EventProcessingAwire, WriteContract { | |||||
| public class WriteContractImpl implements EventProcessingAware, WriteContract { | |||||
| private ContractEventContext eventContext; | private ContractEventContext eventContext; | ||||
| @@ -2,7 +2,7 @@ package com.jd.blockchain.mocker.handler; | |||||
| import com.jd.blockchain.contract.ContractEventContext; | import com.jd.blockchain.contract.ContractEventContext; | ||||
| import com.jd.blockchain.contract.ContractException; | import com.jd.blockchain.contract.ContractException; | ||||
| import com.jd.blockchain.contract.EventProcessingAwire; | |||||
| import com.jd.blockchain.contract.EventProcessingAware; | |||||
| import com.jd.blockchain.contract.LedgerContext; | import com.jd.blockchain.contract.LedgerContext; | ||||
| import com.jd.blockchain.crypto.HashDigest; | import com.jd.blockchain.crypto.HashDigest; | ||||
| import com.jd.blockchain.ledger.BlockchainIdentity; | import com.jd.blockchain.ledger.BlockchainIdentity; | ||||
| @@ -44,7 +44,7 @@ public class MockerContractExeHandle implements OperationHandle { | |||||
| MockerContractEventContext contractEventContext = new MockerContractEventContext(ledgerHash, | MockerContractEventContext contractEventContext = new MockerContractEventContext(ledgerHash, | ||||
| contractOP.getEvent(), requestContext.getRequest(), ledgerContext); | contractOP.getEvent(), requestContext.getRequest(), ledgerContext); | ||||
| EventProcessingAwire eventProcessingAwire = (EventProcessingAwire) executorProxy.getInstance(); | |||||
| EventProcessingAware eventProcessingAwire = (EventProcessingAware) executorProxy.getInstance(); | |||||
| try { | try { | ||||
| // | // | ||||
| // Before处理过程 | // Before处理过程 | ||||