package com.yoghurt.crypto.transactions.client.ui; import com.google.gwt.core.client.GWT; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.uibinder.client.UiHandler; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.DeckPanel; import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.Widget; import com.google.inject.Inject; import com.google.inject.Singleton; import com.yoghurt.crypto.transactions.client.di.BitcoinPlaceRouter; import com.yoghurt.crypto.transactions.client.i18n.M; import com.yoghurt.crypto.transactions.client.util.script.ExecutionStep; import com.yoghurt.crypto.transactions.client.util.script.StackMachine; import com.yoghurt.crypto.transactions.client.widget.ScriptExecutionViewer; import com.yoghurt.crypto.transactions.client.widget.ScriptHexViewer; import com.yoghurt.crypto.transactions.client.widget.ScriptStateViewer; import com.yoghurt.crypto.transactions.client.widget.ScriptViewer; import com.yoghurt.crypto.transactions.client.widget.TransactionViewer; import com.yoghurt.crypto.transactions.client.widget.ValueViewer; import com.yoghurt.crypto.transactions.shared.domain.RawTransactionContainer; import com.yoghurt.crypto.transactions.shared.domain.ScriptInformation; import com.yoghurt.crypto.transactions.shared.domain.ScriptType; import com.yoghurt.crypto.transactions.shared.util.ScriptEncodeUtil; @Singleton public class ScriptViewImpl extends Composite implements ScriptView { interface ScriptViewImplUiBinder extends UiBinder<Widget, ScriptViewImpl> {} private static final ScriptViewImplUiBinder UI_BINDER = GWT.create(ScriptViewImplUiBinder.class); @UiField(provided = true) TransactionViewer hashViewer; @UiField ValueViewer indexViewer; @UiField ScriptHexViewer pubKeySigHexViewer; @UiField ScriptHexViewer scriptSigHexViewer; @UiField DeckPanel scriptExecutionContainer; @UiField Label scriptExecutionResult; @UiField(provided = true) ScriptViewer scriptSigViewer; @UiField(provided = true) ScriptViewer pubKeySigViewer; @UiField ScriptExecutionViewer fullScriptViewer; @UiField Label previousExecutionStep; @UiField Label nextExecutionStep; private int step; @Inject public ScriptViewImpl(final BitcoinPlaceRouter router) { hashViewer = new TransactionViewer(router, false, false); scriptSigViewer = new ScriptViewer(ScriptType.SCRIPT_SIG, false); pubKeySigViewer = new ScriptViewer(ScriptType.SCRIPT_PUB_KEY, false); initWidget(UI_BINDER.createAndBindUi(this)); } private void updateStepCounter() { previousExecutionStep.setText(step == 0 ? "" : "<== step " + step); nextExecutionStep .setText(step >= scriptExecutionContainer.getWidgetCount() - 1 ? "" : "step " + (step + 2) + " ==>"); } @UiHandler("nextExecutionStep") public void onNextExecutionClick(final ClickEvent e) { if (step >= scriptExecutionContainer.getWidgetCount() - 1) { return; } scriptExecutionContainer.showWidget(++step); updateStepCounter(); } @UiHandler("previousExecutionStep") public void onPreviousExecutionClick(final ClickEvent e) { if (step <= 0) { return; } scriptExecutionContainer.showWidget(--step); updateStepCounter(); } @Override public void setScript(final ScriptInformation information, final StackMachine stackMachine) { hashViewer.setValue(information.getOutpoint().getReferenceTransaction()); indexViewer.setValue(information.getOutpoint().getIndex()); pubKeySigViewer.setScript(information.getPubKeySig().getInstructions()); scriptSigViewer.setScript(information.getScriptSig().getInstructions()); fullScriptViewer.setScript(stackMachine.getScript()); final RawTransactionContainer rawPubKeySigContainer = new RawTransactionContainer(); ScriptEncodeUtil.encodeScript(information.getPubKeySig(), rawPubKeySigContainer, ScriptType.SCRIPT_PUB_KEY); final RawTransactionContainer rawScriptSigContainer = new RawTransactionContainer(); ScriptEncodeUtil.encodeScript(information.getScriptSig(), rawScriptSigContainer, ScriptType.SCRIPT_SIG); pubKeySigHexViewer.setValue(rawPubKeySigContainer); scriptSigHexViewer.setValue(rawScriptSigContainer); scriptExecutionContainer.clear(); int counter = 1; for(final ExecutionStep state : stackMachine) { final ScriptStateViewer scriptViewer = new ScriptStateViewer(state, counter); scriptExecutionContainer.add(scriptViewer); if(state.hasExecutionError()) { break; } counter++; } if(stackMachine.hasExecutionError()) { scriptExecutionResult.setText(M.messages().scriptPlaceExecutionResultFailureTriggered()); } else if(stackMachine.getStack().isEmpty() || stackMachine.getStack().peek().getBytes().length == 0) { scriptExecutionResult.setText(M.messages().scriptPlaceExecutionResultFailureResult()); } else { scriptExecutionResult.setText(M.messages().scriptPlaceExecutionResultSuccess()); } scriptExecutionContainer.showWidget(0); updateStepCounter(); } }