defmodule BitcoinLib.Script.Opcodes.Stack.TwoDup do @moduledoc """ Based on https://en.bitcoin.it/wiki/Script Word OP_2DUP Opcode 110 Hex 0x6e Input x1 x2 Output x1 x2 x1 x2 Duplicates the top two stack items. """ @behaviour BitcoinLib.Script.Opcode defstruct [] alias BitcoinLib.Script.Opcodes.Stack.TwoDup @type t :: TwoDup @value 0x6E @doc """ Returns 0x6e ## Examples iex> BitcoinLib.Script.Opcodes.Stack.TwoDup.v() 0x6e """ @spec v() :: 0x6E def v do @value end @doc """ Returns <<0x6e>> ## Examples iex> BitcoinLib.Script.Opcodes.Stack.TwoDup.encode() <<0x6e>> """ def encode() do <<@value::8>> end @doc """ Duplicates the top stack item. ## Examples iex> stack = [4, 3, 5] ...> %BitcoinLib.Script.Opcodes.Stack.TwoDup{} ...> |> BitcoinLib.Script.Opcodes.Stack.TwoDup.execute(stack) {:ok, [4, 3, 4, 3, 5]} """ @spec execute(TwoDup.t(), list()) :: {:ok, list()} | {:error, binary()} def execute(_opcode, []), do: {:error, "trying to execute OP_2DUP on an empty stack"} def execute(_opcode, [_]), do: {:error, "trying to execute OP_2DUP on a one element stack"} def execute(_opcode, [first, second] ++ remaining) do {:ok, [first, second, first, second] ++ remaining} end end