@@ -49,6 +49,114 @@ import Plutus.V1.Ledger.Api (
4949import Prettyprinter (pretty , (<+>) )
5050import Prelude
5151
52+ {-
53+
54+ The coin selection algorithm works as follows:
55+
56+ we can think of a value with different native tokens and ada as vectors of n-dimension.
57+
58+ Eg:
59+
60+ Values:
61+
62+ value1: [("ScriptHash1", "TokenName1", 1), ("", "", 1)]
63+ value2: [("ScriptHash1", "TokenName1", 2), ("ScriptHash2", "TokenName2", 2), ("", "", 2)]
64+
65+ Converting Values to vectors:
66+
67+ Here each column in the vector will represent the following assetClass:
68+
69+ [("ScriptHash1", "TokenName1"), ("ScriptHash2", "TokenName2"), ("", "")]
70+
71+ value1-vector: [1, 0, 1 ]
72+ value2-vector: [2, 2, 2 ]
73+
74+ Each element of the vector represents corresponding native tokens and ada, if a native token
75+ is not present in a value then we fill it with zero.
76+
77+ If we think of all the values as vector, then we can think of coin selection
78+ and balancing problem in the following way:
79+
80+ we have an output vector and many input vectors, and the goal is to get as close to the output vector
81+ as possible using all the combinations of input vectors.
82+ Now, since we think of value as vectors we can define what "close" will be,
83+ which is just the euclidean distance.
84+
85+ Now, let's see how the coin selection works by looking at an example:
86+
87+ Eg: consider a Tx with two outputs and three utxos at user's wallet.
88+
89+ output1 : [("scriptHash1", "TokenName1", 1), ("", "", 1)]
90+ output2 : [("", "", 2)]
91+ Fee : [("", "", 3)]
92+
93+ -- These are the utxos at user's wallet
94+ utxo1 : [("scriptHash1", "TokenName1", 10), ("", "", 10)]
95+ utxo2 : [("", "", 5)]
96+ utxo3 : [("scriptHash1", "TokenName1", 3), ("", "", 6)]
97+
98+ First we will convert all our values into vectors::
99+
100+ [("scriptHash1", "TokenName1"), ("", "")]
101+ output-vector: [1, 6] -- Just Adding output1 + output2 + Fee
102+
103+ utxo1-vector: [10, 10]
104+ utxo2-vector: [0, 5]
105+ utxo3-vector: [3, 6]
106+
107+ Now, as stated above our goal is to get as close to output-vector as possible,
108+ but we also need to satisfiy the following condition:
109+
110+ 1. Each column of the resultant vector must be greater than or equal to the corresponding
111+ column of the output vector.
112+
113+ In this case this means that, the resultant vector [x , y] should be such that
114+ x >= 1 and y >= 6.
115+
116+ 2. The input vector must not be the zero vector.
117+
118+ Currently we don't have any inputs to the Tx, hence the input vector will be zero vector:
119+
120+ input-vector: [0, 0]
121+
122+ Now, we can start searching for utxos that can statisfy our goal and mission:
123+
124+ step 1. Add input vector to all the utxo vectors. In this case these vectors will be
125+ utxo1-vector, utxo2-vector, utxo3-vector.
126+
127+ Result: [10, 10], [0, 5], [3, 6] (adding zero vector does not change the vector).
128+
129+ step 2. calculate distances of previously added vectors with output vector.
130+
131+ Result: [ 9.84 -- l2norm(output-vector, utxo1-vector)
132+ , 1.41 -- l2norm(output-vector, utxo2-vector)
133+ , 2.00 -- l2norm(output-vector, utxo3-vector)
134+ ]
135+
136+ As, we can see the distance between utxo1-vector and output-vector is very large
137+ which is to be expected as utxo1-vector contains lots of "value" of different assetclass.
138+
139+ step 3. sort the distances, and select the utxos with least distances
140+ until all the conditions are statisfied.
141+
142+ Result: [ 1.41
143+ , 2.00
144+ , 9.84
145+ ]
146+
147+ Since, utxo2-vector has the least distance we will select that utxo.
148+
149+ But, selecting utxo2-vector alone doesn't statisfy all our conditions,
150+ hence we will have to continue selecting. After utxo2-vector, the vector with
151+ least distance is utxo3-vector, hence we will select that vector.
152+
153+ Now, the input vector is: [3, 11] (which is just addition of utxo2-vector & utxo3-vector).
154+
155+ Since, this input vector statisfy all our conditions, we will select utxo2 & utxo3 as inputs
156+ to our Tx.
157+
158+ -}
159+
52160-- 'searchStrategy' represents the possible search strategy.
53161data SearchStrategy
54162 = -- | This is a greedy search that searches for nearest utxo using l2norm.
0 commit comments