Bitcoin P2WSH


In 2015, Bitcoin developers came up with major improvements that known as Segregated Witness – SegWit and it has been mainly mentioned in BIP141 & BIP143. This improvement aims to solve
  • Scalability of bitcoin network.
  • Malleability transaction for lightning network solution.
  • Increase block size limit.

  • P2WSH stands for "Pay To Witness Script Hash".
  • Address applies BECH32 encoding.
  • In Bitcoin, bc represents mainnet and tb represents testnet.
Script Pair of P2WSH
ScriptPubKey: OP_HASH160 20<32 Bytes RedeemScriptHash> OP_EQUAL
ScriptSig: (Empty as ScriptSig has been moved to witness field.)
Witness Field: <Witness Items> <RedeemScript>

Witness Structure

The witness is a serialization of all witness data of the transaction. Each txin is associated with a witness field. A witness field starts with a var_int to indicate the number of stack items for the txin. It is followed by stack items, with each item starts with a var_int to indicate the length. Witness data is NOT script, therefore you cannot use OPCODES. See BIP 141.

WitnessSerialization of Witness Data.
Witness DataAll Witness Fields.
Witness FieldWitness field can refer to its txIn, start with var_int to indicate number of stack items.
Stack ItemStarts with a var_int to indicate the length.


P2WSH Address

<?php 
use BitWasp\Bitcoin\Address\SegwitAddress;
use BitWasp\Bitcoin\Bitcoin;
use BitWasp\Buffertools\Buffer;
use BitWasp\Bitcoin\Network\NetworkFactory;
use BitWasp\Bitcoin\Script\WitnessProgram;
use BitWasp\Bitcoin\Script\ScriptFactory;

include_once "../libraries/vendor/autoload.php";
include_once("html_iframe_header.php");

if ($_SERVER['REQUEST_METHOD'] == 'POST') {
	try {
		
		$networkClass   = $_POST['network'];
		Bitcoin::setNetwork(NetworkFactory::$networkClass());
		$network        = Bitcoin::getNetwork();
		
		$witnessScript = ScriptFactory::fromHex($_POST['redeem_script']);
		$witnessScriptHash = $witnessScript->getWitnessScriptHash();/*sha256*/
		$p2wshWP = WitnessProgram::v0($witnessScriptHash);
		
		$p2wsh = new SegwitAddress($p2wshWP);
	?>
		<div class="table-responsive">
			<table border=0 class='table'>
				<tr style='background-color:#f0f0f0'><td>Bech32 Address</td><td><?php echo $p2wsh->getAddress()?></td></tr>
				<tr><td><span data-toggle="tooltip" title="Witness script is redeem script in P2WSH version" class='explaination'>Witness Script Hex</span></td><td><?php echo $witnessScript->getHex()?></td></tr>
				<tr><td>Witness Script Asm</td>
					<td>
					<?php
					$opcodes = $witnessScript->getOpcodes();
					
					foreach( $witnessScript->getScriptParser()->decode() as $operation ) {
							
							try {
								$op = $opcodes->getOp($operation->getOp());
							} catch (\RuntimeException $e) {
								$op = "";
							}
							
							echo $op ? $op . " " : "";
							
							if ($op != 'OP_0' AND $operation->isPush()) {
								$bytes = (int)ltrim($op, 'OP_PUSHDATA');
								$bytes = $bytes > 0 ? $bytes : 1;
								
								$hexsize = Buffer::int($operation->getDataSize(), $bytes)->getHex();
								echo htmlentities("{$hexsize}<{$operation->getData()->getHex()}> ");
							} 
						}
					
					?>
					</td>
				</tr>
				<tr><td>Witness Version</td><td><?php echo $p2wshWP->getVersion()?></td></tr>
				<tr><td>Witness Program</td><td><?php echo $p2wshWP->getProgram()->getHex()?></td></tr>
				
				<tr style='background-color:#f0f0f0'><td>ScriptPubKey Hex </td><td><?php echo $p2wshWP->getScript()->getHex()?></td></tr>
				<tr style='background-color:#f0f0f0'><td>ScriptPubKey Asm</td>
					<td>
						<?php 
						$opcodes = $p2wshWP->getScript()->getOpcodes();
						
						foreach( $p2wshWP->getScript()->getScriptParser()->decode() as $operation ) {
							
							try {
								$op = $opcodes->getOp($operation->getOp());
							} catch (\RuntimeException $e) {
								$op = "";
							}
							
							echo $op ? $op . " " : "";
							
							if ($op != 'OP_0' AND $operation->isPush()) {
								$bytes = (int)ltrim($op, 'OP_PUSHDATA');
								$bytes = $bytes > 0 ? $bytes : 1;
								
								$hexsize = Buffer::int($operation->getDataSize(), $bytes)->getHex();
								echo htmlentities("{$hexsize}<{$operation->getData()->getHex()}> ");
							} 
						}
						?>
					</td>
				</tr>
			</table>
		</div>
<?php 
	} catch (Exception $e) {
		$errmsg .= "Problem found. " . $e->getMessage();

	}
} 

if ($errmsg) {
?>
	<div class="alert alert-danger">
		<strong>Error!</strong> <?php echo $errmsg?>
	</div>
<?php
}
?>
<form action='' method='post'>
	<div class="form-group">
		<label for="network">Network:</label>
		<select id="network" name="network" class="form-control" >
			<?php
			$networks = get_class_methods(new NetworkFactory());
			foreach($networks as $network) {
				echo "<option value='{$network}'".($network == $_POST['network'] ? " selected": "").">{$network}</option>";
			}
			?>
		</select>
	</div>
	<div class="form-group">
		<label for="redeem_script"><span data-toggle="tooltip" title="Witness script is redeem script in P2WSH version" class='explaination'>Witness Script Hex</span>: </label>
		
		<input class="form-control" type='text' name='redeem_script' id='redeem_script' value='<?php echo $_POST['redeem_script']?>'>
		* This script should be saved and should be shared with all the participants before a payment is made, so they may validate the authenticity of the address, it will also be used later to release the bitcoins.
	</div>
	
	<input type='submit' class="btn btn-success btn-block"/>
</form>
<?php
include_once("html_iframe_footer.php");		

Fund & Spend P2WSH

<?php 
use BitWasp\Bitcoin\Bitcoin;
use BitWasp\Buffertools\Buffer;
use BitWasp\Bitcoin\Key\Factory\PrivateKeyFactory;
use BitWasp\Bitcoin\Network\NetworkFactory;
use BitWasp\Bitcoin\Address\AddressCreator;
use BitWasp\Bitcoin\Address\Bech32AddressInterface;
use BitWasp\Bitcoin\Transaction\Factory\TxBuilder;
use BitWasp\Bitcoin\Transaction\TransactionFactory;
use BitWasp\Bitcoin\Transaction\TransactionOutput;
use BitWasp\Bitcoin\Transaction\Factory\Signer;
use BitWasp\Bitcoin\Script\ScriptFactory;
use BitWasp\Bitcoin\Script\Classifier\OutputClassifier;
use BitWasp\Bitcoin\Script\ScriptType;

include_once "../libraries/vendor/autoload.php";
include_once("html_iframe_header.php");

$noOfInputs = 10;
$noOfOutputs = 10;

if ($_SERVER['REQUEST_METHOD'] == 'POST') {
	try {
		$networkClass   = $_POST['network'];
		
		
		Bitcoin::setNetwork(NetworkFactory::$networkClass());
		
		$network        = Bitcoin::getNetwork();
		$ecAdapter      = Bitcoin::getEcAdapter();
		$privKeyFactory = new PrivateKeyFactory();
		
		$addrCreator = new AddressCreator();
		
		$spendTx = TransactionFactory::build();
		
		$signItems = [];
		
		
		if (!is_numeric($_POST['no_of_inputs']) OR !is_numeric($_POST['no_of_outputs'])) {
			throw new Exception("Error in 'no_of_inputs' or 'no_of_outputs'.");
		}
			
		foreach(range(1,$_POST['no_of_inputs']) as $thisInput) {
			$utxoHash = trim($_POST["utxo_hash_{$thisInput}"]);
			$utxoNOutput = trim($_POST["utxo_n_{$thisInput}"]);
			$privkeyhex = trim($_POST["privkey_{$thisInput}"]);
			$utxoScript = trim($_POST["utxo_script_{$thisInput}"]);
			
			if (strlen($utxoHash)>0 AND strlen($utxoNOutput) > 0 AND strlen($privkeyhex) > 0) {
				$spendTx = $spendTx->input($utxoHash, $utxoNOutput);
				$signItems[] = [$privkeyhex, $utxoScript];
			} else {
				throw new Exception("Error in 'input#{$thisInput}'.");
			}
		}
		
		foreach(range(1,$_POST['no_of_outputs']) as $thisOutput) {
			
			$address = trim($_POST["address_{$thisOutput}"]);
			$amount = trim($_POST["amount_{$thisOutput}"]);
			
			$recipient = $addrCreator->fromString($address);
			
			if (!strlen($address) or !strlen($amount)) {
				throw new Exception("Error in 'output#{$thisOutput}'.");
			}
			
			if (!$recipient instanceof Bech32AddressInterface) {
				throw new Exception("Invalid P2WSH address in 'output#{$thisOutput}' (Check bech32Address).");
			} 
			
			$decodeScript = (new OutputClassifier())->decode($recipient->getScriptPubKey());
			
			if ($decodeScript->getType() != ScriptType::P2WSH) {
				throw new Exception("Invalid P2WSH address in 'output#{$thisOutput}' (Check scriptPubKey).");
			}
			
			$spendTx = $spendTx->payToAddress($amount, $recipient);
		}
		
		$thisTx = $spendTx->get();
		
		$signer = new Signer($thisTx, $ecAdapter);
		
		foreach($signItems as $nIn=>$signItem) {
			$privateKey = $privKeyFactory->fromHexCompressed($signItem[0]);
			
			$scriptPubKey = ScriptFactory::fromHex($signItem[1]);
			
			
			$txOutput = new TransactionOutput(0, $scriptPubKey );
			$signer = $signer->sign($nIn, $privateKey, $txOutput);
			
		}
		
	?>
		<div class="alert alert-success">
			<h6 class="mt-3">Final TX Hex</h6>
			
			<textarea class="form-control" rows="5" id="comment" readonly><?php echo $signer->get()->getHex();?></textarea>
		</div>
	<?php
	
	} catch (Exception $e) {
		$errmsg .= "Problem found. " . $e->getMessage();

	}
}

if ($errmsg) {
?>
	<div class="alert alert-danger">
		<strong>Error!</strong> <?php echo $errmsg?>
	</div>
<?php
}
?>
<form action='' method='post'>
	<div class="form-group">
		<label for="network">Network: </label>
		<select name="network" id="network" class="form-control">
			<?php
			$networks = get_class_methods(new NetworkFactory());
			foreach($networks as $network) {
				echo "<option value='{$network}'".($network == $_POST['network'] ? " selected": "").">{$network}</option>";
			}
			?>
		</select>
	</div>
	
	<div class="row">
		<div class="col-sm-6">
			
			<div class="form-row">
				<div class="form-group col">
					<label for="no_of_inputs">Inputs: </label> 
					<select class="form-control" id="no_of_inputs" name='no_of_inputs' style='width:auto;' onchange="
					var self = $(this);
					var thisvalue = self.val();
					var form = self.closest('form');
					$('div[id^=row_input_]',form).hide();
					for(var i=1; i<= thisvalue; i++) { 
						$('div[id=row_input_'+  i + ']',form).show();
					}
					">
						<?php
						foreach(range(1,$noOfInputs) as $thisInput) {
							echo "<option value='{$thisInput}'".($thisInput == $_POST['no_of_inputs'] ? " selected": "").">{$thisInput}</option>";
						}
						?>
					</select>
				</div>
			</div>
			
			<?php
			$selectedNInputs = is_numeric($_POST['no_of_inputs']) ? $_POST['no_of_inputs'] : 1;
			
			foreach(range(1,$noOfInputs) as $thisInput) {
			?>
			
				<div class="form-row" id='row_input_<?php echo $thisInput?>' style="<?php echo ($thisInput > $selectedNInputs) ? "display:none" : "display:;"?>">
				
					<div class="form-group  col-sm-1">
						#<?php echo $thisInput?> 
					</div>
					<div class="form-group  col-sm-3">
						
						<input class="form-control" title="UTXO Tx Hash" placeholder='UTXO Tx Hash' type='text' name='utxo_hash_<?php echo $thisInput?>' value='<?php echo $_POST["utxo_hash_{$thisInput}"]?>'>
					</div>
					<div class="form-group  col-sm-1">
						<input class="form-control" title="UTXO N Output" placeholder='N' type='text' name='utxo_n_<?php echo $thisInput?>' value='<?php echo $_POST["utxo_n_{$thisInput}"]?>'>
					</div>
					
					<div class="form-group  col-sm-3">
						<input class="form-control" title="UTXO ScriptPubKey" placeholder='UTXO ScriptPubKey' type='text' name='utxo_script_<?php echo $thisInput?>' value='<?php echo $_POST["utxo_script_{$thisInput}"]?>'>
					</div>
					<div class="form-group  col-sm-4">
						<input class="form-control" title="Private Key Hex, for signing purpose." placeholder='Private Key Hex' type='text' name='privkey_<?php echo $thisInput?>' value='<?php echo $_POST["privkey_{$thisInput}"]?>'>
					</div>
				</div>
			<?php
			}
			?>
		</div>
		<div class="col-sm-6">
			<div class="form-row">
				<div class="form-group col">
					<label for="no_of_outputs">Outputs:</label> <select class="form-control" id="no_of_outputs" name='no_of_outputs' style='width:auto;' onchange="
					var self = $(this);
					var thisvalue = self.val();
					var form = self.closest('form');
					$('div[id^=row_output_]',form).hide();
					for(var i=1; i<= thisvalue; i++) { 
						$('div[id=row_output_'+  i + ']',form).show();
					}
					">
						<?php
						foreach(range(1,$noOfOutputs) as $thisOutput) {
							echo "<option value='{$thisOutput}'".($thisOutput == $_POST['no_of_outputs'] ? " selected": "").">{$thisOutput}</option>";
						}
						?>
					</select>
				</div>
			</div>
			<?php
			$selectedNOutputs = is_numeric($_POST['no_of_outputs']) ? $_POST['no_of_outputs'] : 1;
			
			
			foreach(range(1,$noOfOutputs) as $thisOutput) {
			?>
				<div class="form-row" id='row_output_<?php echo $thisOutput?>' style="<?php echo ($thisOutput > $selectedNOutputs) ? "display:none" : "display:;"?>">
					<div class="form-group col-sm-1">
						#<?php echo $thisOutput?> 
					</div>
					
					<div class="form-group col-sm-6">
						<input class="form-control" placeholder='P2WSH Address' type='text' name='address_<?php echo $thisOutput?>' value='<?php echo $_POST["address_{$thisOutput}"]?>'>
					</div>
					<div class="form-group col-sm-5">
						<input class="form-control" placeholder='Amount' type='text' name='amount_<?php echo $thisOutput?>' value='<?php echo $_POST["amount_{$thisOutput}"]?>'>
					</div>
				</div>
	<?php
			}
	?>
		</div>
	</div>
	<input type='submit' class="btn btn-success btn-block"/>
</form>
<?php
include_once("html_iframe_footer.php");		
<?php 
use BitWasp\Buffertools\Buffer;
use BitWasp\Bitcoin\Address\AddressCreator;
use BitWasp\Bitcoin\Address\PayToPubKeyHashAddress;
use BitWasp\Bitcoin\Bitcoin;
use BitWasp\Bitcoin\Key\Factory\PrivateKeyFactory;
use BitWasp\Bitcoin\Network\NetworkFactory;
use BitWasp\Bitcoin\Transaction\Factory\Signer;
use BitWasp\Bitcoin\Transaction\TransactionFactory;
use BitWasp\Bitcoin\Script\ScriptFactory;
use BitWasp\Bitcoin\Script\ScriptWitness;
use BitWasp\Bitcoin\Script\Classifier\OutputClassifier;
use BitWasp\Bitcoin\Script\ScriptType;
    
include_once "../libraries/vendor/autoload.php";

$noOfInputs = 10;
$noOfOutputs = 10;

if ($_SERVER['REQUEST_METHOD'] == 'GET' AND $_GET['ajax'] == '1') {
	$data = [];
	if (!ctype_xdigit($_GET['utx'])) {
		$data = ["error"=>"UTX must be hex."];
	} else {
		$utxHex = $_GET['utx'];
		$utx = TransactionFactory::fromHex($utxHex);
		$outputs = $utx->getOutputs();
		
		$data['txHash'] = $utx->getTxHash()->flip()->getHex();//swap endianess
		$data['outputs'] = [];
		if (@count($outputs)) {
			foreach($outputs as $k=>$output) {
				if ($k < 10) { //limit to retrieve max 10 inputs only
				
					$decodeScript = (new OutputClassifier())->decode($output->getScript());
						
					if ($decodeScript->getType() != ScriptType::P2WSH) {
						$data = ["error"=>"Load fail! Your unspent transaction output (utxo) can only contain P2WSH ScriptPubKey."];
						break;
					}
					$data['outputs'][] = ["amount"=>$output->getValue(), "n"=>$k, "scriptPubKey"=>$output->getScript()->getHex()];
				}
			}
		}
	}
	
	die(json_encode($data));
}

include_once("html_iframe_header.php");

if ($_SERVER['REQUEST_METHOD'] == 'POST') {
	
	try {
		$networkClass   = $_POST['network'];
		Bitcoin::setNetwork(NetworkFactory::$networkClass());
		
		$network        = Bitcoin::getNetwork();
		$ecAdapter      = Bitcoin::getEcAdapter();
		
		$addrCreator = new AddressCreator();
		
		$spendTx = TransactionFactory::build();
		
		if (!strlen($_POST['utx']) or !ctype_xdigit($_POST['utx'])) {                    
			throw new Exception("UTX must be hex.");
		} 
		
		if (!is_numeric($_POST['no_of_inputs']) OR !is_numeric($_POST['no_of_outputs'])) {
			throw new Exception("Error in 'no_of_inputs' or 'no_of_outputs'.");
		}
		
		$utxHex = $_POST['utx'];
		$utx = TransactionFactory::fromHex($utxHex);    
		$utxos = $utx->getOutputs();
		
		$witnessStacks = [];
		foreach($utxos as $k=>$utxo) {
			$spendTx = $spendTx->spendOutputFrom($utx, $k);
			
			$stackitems = $_POST["stackitem_" . ($k+1)];
			$witnessScript = ScriptFactory::fromHex($_POST['witnessscript_' . ($k+1)]);
			$utxoScript = $utxo->getScript()->getHex();
			$utxoAmount = $utxo->getValue();
			
			$scriptPubKey = ScriptFactory::scriptPubKey()->p2wsh($witnessScript->getWitnessScriptHash()/*sha256*/);
			
			if ($utxoScript != $scriptPubKey->getHex()) {
				throw new Exception("Error in 'input#{$k}'. Witness script is not matched to UTXO's ScriptPubKey.");
			}
			
			if (!count($stackitems)) {
				throw new Exception("Error in 'input#{$k}'. You must put at least one stack item.");
			}
			
			$thisWitnessStacks = [];
			foreach($stackitems as $stackitem) {
				$thisWitnessStacks[] = Buffer::hex($stackitem);
			}
			
			$thisWitnessStacks[] = $witnessScript->getBuffer();
								
			if (@count($thisWitnessStacks)) {
				
				$witnessStacks[] = new ScriptWitness(...$thisWitnessStacks);
				
			}
		}
				
		foreach(range(1,$_POST['no_of_outputs']) as $thisOutput) {
			
			$address = trim($_POST["address_{$thisOutput}"]);
			$amount = trim($_POST["amount_{$thisOutput}"]);
			
			if (!strlen($address) or !strlen($amount)) {
				throw new Exception("Error in 'output#{$thisOutput}'.");
				
			} 
			
			$recipient = $addrCreator->fromString($address);    
			$spendTx = $spendTx->payToAddress($amount, $recipient);
			
		}
		
		//lastly, append witness
		$spendTx = $spendTx->witnesses($witnessStacks);
		
		$thisTx = $spendTx->get();
		
		
	?>
		<div class="alert alert-success">
			<h6 class="mt-3">Final TX Hex</h6>
			<textarea class="form-control" rows="5" id="comment" readonly><?php echo $thisTx->getHex();?></textarea>
			<div class="table-responsive">
				<table class='table'>
					<tr><td><span data-toggle="tooltip" class='explaination' title='([nVersion][txins][txouts][nLockTime]).serialize().sha256d();'>TxId</span></td><td><?php echo $thisTx->getTxId()->getHex()?></td></tr>
					
					<tr><td><span data-toggle="tooltip" class='explaination' title='([nVersion][marker][flag][txins][txouts][witness][nLockTime]).serialize().sha256d();'>WtxId</span></td><td><?php echo $thisTx->getWitnessTxId()->getHex()?></td></tr>
					
				</table>
			</div>
			
			<h6 class="mt-3">Base Serialized Transaction (Without Witness)</h6>
			<textarea class="form-control" rows="5" id="comment" readonly><?php echo $thisTx->getBaseSerialization()->getHex();?></textarea>
			
			<?php 
			
			#debug( $thisTx->getWitnessSerialization());
			?>
			
		</div>
	<?php
	
	} catch (Exception $e) {
		$errmsg .= "Problem found. " . $e->getMessage();

	}
}

if ($errmsg) {
?>
	<div class="alert alert-danger">
		<strong>Error!</strong> <?php echo $errmsg?>
	</div>
<?php
}
?>
<form action='' method='post'>
	<div class="form-group">
		<label for="network">Network: </label>
		<select name="network" id="network" class="form-control">
			<?php
			$networks = get_class_methods(new NetworkFactory());
			foreach($networks as $network) {
				echo "<option value='{$network}'".($network == $_POST['network'] ? " selected": "").">{$network}</option>";
			}
			?>
		</select>
	</div>
	<div class="form-group">
		<label for="utx">Unspent Transaction (Hex):</label>
		
		<div class="input-group mb-3">
			<input class="form-control" type='text' name='utx' id='utx' value='<?php echo $_POST['utx']?>'>
			<div class="input-group-append">
				<input class="btn btn-success" type="button" id="load" value="Load" onclick="
				var self = $(this);
				self.val('......'); 
				
				var form = self.closest('form');
				var allInputDivs = form.find('div[id^=row_input_]');
				var allInputs = $( ':input', allInputDivs );
				allInputs.val('');
				allInputDivs.hide();
				$('select#no_of_inputs',form).empty();
				$('span#total_inputs',form).html('0');
				$.ajax({
					url: '?ajax=1&utx=' + $('input#utx',form).val(), 
					success:function(result){
						try {
							j = eval('(' + result + ')');
							
							if ('error' in j && j.error.length>0) {
								var error = true;
							} else {
								var error = false;
							}
							
							if (!error) {
								var txHash = j.txHash;
								var outputs = j.outputs;
								var totalInputs = 0;
								
								if (outputs.length > 0) {
									$('select#no_of_inputs',form).prepend('<option value=\''+outputs.length+'\' selected=\'selected\'>'+outputs.length+'</option>');
									
									var x;    
									for (x in outputs) {
										var divid = parseInt(x) + 1;
										var amount = parseInt(outputs[x].amount);
										totalInputs += amount;
										
										$('div#row_input_' + divid             ,form).show();
										$('input[name=utxo_hash_' + divid+']'  ,form).val(txHash);
										$('input[name=utxo_n_' + divid+']'     ,form).val(outputs[x].n);
										$('input[name=utxo_script_' + divid+']',form).val(outputs[x].scriptPubKey);
										$('input[name=utxo_amount_' + divid+']',form).val(amount);
										
										
										var stackItemSelector = $('input[name=\'stackitem_'+divid+'[]\']'      ,form).parent(); //div.input-group
										var firstStackItemInput = stackItemSelector.filter(':first');
										stackItemSelector.not(':first').remove();
										
										firstStackItemInput.closest('div').find('input[type=button]').val('+');
									}
								}
								
								$('span#total_inputs',form).html(totalInputs);
							} else {
								alert(j.error);
							}
						} catch(e) {
							alert('Invalid Json Format.');
						}
					},
					complete:function() {
						self.val('Load');
					}
				});
				"/>
			</div>
		</div>
		<!--* This sample will extract UTX Outputs from provided UTX Hex-->
	</div>
	<div class="row">
		<div class="col-sm-6">
			
			<div class="form-row">
				<div class="form-group col">
					<label for="no_of_inputs">Inputs: <i>Max 10 inputs only. Please load them from UTX above.</i></label> 
					
					<div class="row">
						<div class="col-sm-2">
							<select class="form-control" id="no_of_inputs" name='no_of_inputs' style='width:auto;' onchange="
							var self = $(this);
							var thisvalue = self.val();
							var form = self.closest('form');
							$('div[id^=row_input_]',form).hide();
							for(var i=1; i<= thisvalue; i++) { 
								$('div[id=row_input_'+  i + ']',form).show();
							}
							" readonly>
								<?php
								$optionval = $_POST['no_of_inputs']?$_POST['no_of_inputs'] : 0;
								
								if ($optionval > 0) {
								?>
								<option value='<?php echo $optionval?>'><?php echo $optionval?></option>
								<?php
								}
								?>
							</select>
						</div>
						
						<div class="col-sm-10">
							Total Sathoshi: 
							<span id='total_inputs'>
							<?php echo 
							array_reduce(
								array_keys($_POST),
								function($carry, $key) { 
									if (preg_match('/^utxo_amount_/', $key)) {
										return $carry + (int)$_POST[$key];
									} else {                    
										return $carry;
									}
								}, 0
							);?>
							</span>
						</div>
					</div>
				</div>
			</div>
			
			<?php
			$selectedNInputs = is_numeric($_POST['no_of_inputs']) ? $_POST['no_of_inputs'] : 0;
			
			foreach(range(1,$noOfInputs) as $thisInput) {
			?>
			
				<div class="form-row" id='row_input_<?php echo $thisInput?>' style="<?php echo ($thisInput > $selectedNInputs) ? "display:none" : "display:;"?>">
					<input type='hidden' name='utxo_amount_<?php echo $thisInput?>' value='<?php echo $_POST["utxo_amount_{$thisInput}"]?>'/>
					
					<div class="form-group  col-sm-1">
						#<?php echo $thisInput?> 
					</div>
					<div class="form-group  col-sm-3">    
						<input class="form-control" title="UTXO Tx Hash" placeholder='UTXO Tx Hash' type='text' name='utxo_hash_<?php echo $thisInput?>' value='<?php echo $_POST["utxo_hash_{$thisInput}"]?>' readonly>
					</div>
					<div class="form-group  col-sm-1">
						<input class="form-control" title="UTXO N Output" placeholder='N' type='text' name='utxo_n_<?php echo $thisInput?>' value='<?php echo $_POST["utxo_n_{$thisInput}"]?>' readonly>
					</div>
					<div class="form-group  col-sm-3">
						<input class="form-control" title="UTXO ScriptPubKey" placeholder='UTXO ScriptPubKey' type='text' name='utxo_script_<?php echo $thisInput?>' value='<?php echo $_POST["utxo_script_{$thisInput}"]?>' readonly>
					</div>
					<div class="form-group  col-sm-4">
						<?php
						$count = count($_POST["stackitem_{$thisInput}"]);
						$count = $count > 0 ? $count : 1;
						
						foreach(range(0, $count-1) as $arrayIdx) {
							$operator = !$arrayIdx ? '+' : '-';
						?>
						<div class="input-group">
							<input class="form-control" title="" placeholder='Stack Item (Hex)' type='text' name='stackitem_<?php echo $thisInput?>[]' value='<?php echo $_POST["stackitem_{$thisInput}"][$arrayIdx]?>'>
							<div class="input-group-append">
								<input class="btn btn-success" type="button" value="<?php echo $operator?>" rel="<?php echo $thisInput?>" onclick="
								var self = $(this);
								var value = self.attr('value');
								var inputIndex = self.attr('rel');
								
								if (value == '+') {
									var formGroup = self.closest('.form-group');
									var cloneInputGroup = formGroup.find('div').filter(':first').clone();
									cloneInputGroup.find('input[type=button]').val('-');
									formGroup.append(cloneInputGroup);
								} else {
									self.parent('div').parent('div').remove();
								}    
								"/>
							</div>
						</div>
						<?php
						}
						?>
					</div>
					<div class="form-group  col-sm-1">
					</div>
					<div class="form-group  col-sm-11">
						<input class="form-control" title="Enter Witness Script." placeholder='Enter Witness Script.' type='text' name='witnessscript_<?php echo $thisInput?>' value='<?php echo $_POST["witnessscript_{$thisInput}"]?>'/>
						
					</div>
				</div>
			<?php
			}
			?>
		</div>
		<div class="col-sm-6">
			<div class="form-row">
				<div class="form-group col">
					<label for="no_of_outputs">Outputs:</label> <select class="form-control" id="no_of_outputs" name='no_of_outputs' style='width:auto;' onchange="
					var self = $(this);
					var thisvalue = self.val();
					var form = self.closest('form');
					$('div[id^=row_output_]',form).hide();
					for(var i=1; i<= thisvalue; i++) { 
						$('div[id=row_output_'+  i + ']',form).show();
					}
					">
						<?php
						foreach(range(1,$noOfOutputs) as $thisOutput) {
							echo "<option value='{$thisOutput}'".($thisOutput == $_POST['no_of_outputs'] ? " selected": "").">{$thisOutput}</option>";
						}
						?>
					</select>
				</div>
			</div>
			<?php
			$selectedNOutputs = is_numeric($_POST['no_of_outputs']) ? $_POST['no_of_outputs'] : 1;
			
			
			foreach(range(1,$noOfOutputs) as $thisOutput) {
			?>
				<div class="form-row" id='row_output_<?php echo $thisOutput?>' style="<?php echo ($thisOutput > $selectedNOutputs) ? "display:none" : "display:;"?>">
					<div class="form-group col-sm-1">
						#<?php echo $thisOutput?> 
					</div>
					
					<div class="form-group col-sm-6">
						<input class="form-control" placeholder='Any Address' type='text' name='address_<?php echo $thisOutput?>' value='<?php echo $_POST["address_{$thisOutput}"]?>'>
					</div>
					<div class="form-group col-sm-5">
						<input class="form-control" placeholder='Amount' type='text' name='amount_<?php echo $thisOutput?>' value='<?php echo $_POST["amount_{$thisOutput}"]?>'>
					</div>
				</div>
	<?php
			}
	?>
		</div>
	</div>
	
	<input type='submit' class="btn btn-success btn-block"/>
</form>
<?php
include_once("html_iframe_footer.php");		








Tutorials
About Us
Contents have been open source in GITHUB. Please give me a ⭐ if you found this helpful :)
Community
Problem? Raise me a new issue.
Support Us
Buy me a coffee. so i can spend more nights for this :)

BTCSCHOOLS would like to present you with more pratical but little theory throughout our tutorials. Pages' content are constantly keep reviewed to avoid mistakes, but we cannot warrant correctness of all contents. While using this site, you agree to accept our terms of use, cookie & privacy policy. Copyright 2019 by BTCSCHOOLS. All Rights Reserved.